diff options
author | Alex Legler <alex@a3li.li> | 2014-12-23 17:49:26 +0100 |
---|---|---|
committer | Alex Legler <alex@a3li.li> | 2014-12-23 17:49:26 +0100 |
commit | e352fff59842ca14fbfd81ee1c4a64297bb598c5 (patch) | |
tree | 153f268484aa5cc41cacf912bdce8c4847df222d /SemanticMediaWiki/tests/phpunit/includes | |
download | extensions-e352fff59842ca14fbfd81ee1c4a64297bb598c5.tar.gz extensions-e352fff59842ca14fbfd81ee1c4a64297bb598c5.tar.bz2 extensions-e352fff59842ca14fbfd81ee1c4a64297bb598c5.zip |
Add initial set of additional extensions
Diffstat (limited to 'SemanticMediaWiki/tests/phpunit/includes')
189 files changed, 31556 insertions, 0 deletions
diff --git a/SemanticMediaWiki/tests/phpunit/includes/Annotator/CategoryPropertyAnnotatorTest.php b/SemanticMediaWiki/tests/phpunit/includes/Annotator/CategoryPropertyAnnotatorTest.php new file mode 100644 index 00000000..bb0ab6f5 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Annotator/CategoryPropertyAnnotatorTest.php @@ -0,0 +1,318 @@ +<?php + +namespace SMW\Tests\Annotator; + +use SMW\Tests\Util\SemanticDataValidator; +use SMW\Tests\Util\SemanticDataFactory; +use SMW\Tests\Util\Mock\MockTitle; + +use SMW\Annotator\CategoryPropertyAnnotator; +use SMW\Annotator\NullPropertyAnnotator; +use SMW\DIWikiPage; +use SMW\Application; +use SMW\Settings; +use SMW\ParserData; + +use ParserOutput; + +/** + * @covers \SMW\Annotator\CategoryPropertyAnnotator + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class CategoryPropertyAnnotatorTest extends \PHPUnit_Framework_TestCase { + + private $semanticDataFactory; + private $semanticDataValidator; + private $application; + + protected function setUp() { + parent::setUp(); + + $this->semanticDataFactory = new SemanticDataFactory(); + $this->semanticDataValidator = new SemanticDataValidator(); + $this->application = Application::getInstance(); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new CategoryPropertyAnnotator( + new NullPropertyAnnotator( $semanticData ), + array() + ); + + $this->assertInstanceOf( + '\SMW\Annotator\CategoryPropertyAnnotator', + $instance + ); + } + + /** + * @dataProvider categoriesDataProvider + */ + public function testAddCategoriesAnnotation( array $parameters, array $expected ) { + + $semanticData = $this->semanticDataFactory + ->setSubject( new DIWikiPage( __METHOD__, $parameters['namespace'], '' ) ) + ->newEmptySemanticData(); + + $this->application->registerObject( + 'Settings', + Settings::newFromArray( $parameters['settings'] ) + ); + + $instance = new CategoryPropertyAnnotator( + new NullPropertyAnnotator( $semanticData ), + $parameters['categories'] + ); + + $instance->addAnnotation(); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance->getSemanticData() + ); + } + + /** + * @dataProvider categoriesDataProvider + */ + public function testAddCategoriesWithParserDataUpdate( array $parameters, array $expected ) { + + $semanticData = $this->semanticDataFactory + ->setSubject( new DIWikiPage( __METHOD__, $parameters['namespace'], '' ) ) + ->newEmptySemanticData(); + + $title = $semanticData->getSubject()->getTitle(); + $parserOutput = new ParserOutput(); + $parserData = new ParserData( $title, $parserOutput ); + + $this->application->registerObject( + 'Settings', + Settings::newFromArray( $parameters['settings'] ) + ); + + $instance = new CategoryPropertyAnnotator( + new NullPropertyAnnotator( $parserData->getSemanticData() ), + $parameters['categories'] + ); + + $instance->addAnnotation(); + $parserData->updateOutput(); + + $parserDataAfterAnnotation = new ParserData( $title, $parserOutput ); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $parserDataAfterAnnotation->getSemanticData() + ); + } + + /** + * @dataProvider hiddenCategoriesDataProvider + */ + public function testAddCategoriesWithHiddenCategories( array $parameters, array $expected ) { + + $expectedPageLookup = $parameters['settings']['smwgShowHiddenCategories'] ? $this->never() : $this->atLeastOnce(); + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage->expects( $expectedPageLookup ) + ->method( 'getHiddenCategories' ) + ->will( $this->returnValue( $parameters['hidCategories'] ) ); + + $pageCreator = $this->getMockBuilder( '\SMW\MediaWiki\PageCreator' ) + ->disableOriginalConstructor() + ->getMock(); + + $pageCreator->expects( $expectedPageLookup ) + ->method( 'createPage' ) + ->will( $this->returnValue( $wikiPage ) ); + + $semanticData = $this->semanticDataFactory + ->setSubject( new DIWikiPage( __METHOD__, $parameters['namespace'], '' ) ) + ->newEmptySemanticData(); + + $this->application->registerObject( + 'Settings', + Settings::newFromArray( $parameters['settings'] ) + ); + + $this->application->registerObject( + 'PageCreator', + $pageCreator + ); + + $instance = new CategoryPropertyAnnotator( + new NullPropertyAnnotator( $semanticData ), + $parameters['categories'] + ); + + $instance->addAnnotation(); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $semanticData + ); + } + + public function categoriesDataProvider() { + + $provider = array(); + + // Standard category + $provider[] = array( + array( + 'namespace' => NS_MAIN, + 'categories' => array( 'Foo', 'Bar' ), + 'settings' => array( + 'smwgUseCategoryHierarchy' => false, + 'smwgCategoriesAsInstances' => true, + 'smwgShowHiddenCategories' => true + ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_INST', + 'propertyValues' => array( 'Foo', 'Bar' ), + ) + ); + + // Category hierarchy or Sub-category + $provider[] = array( + array( + 'namespace' => NS_CATEGORY, + 'categories' => array( 'Foo', 'Bar' ), + 'settings' => array( + 'smwgUseCategoryHierarchy' => true, + 'smwgCategoriesAsInstances' => false, + 'smwgShowHiddenCategories' => true + ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_SUBC', + 'propertyValues' => array( 'Foo', 'Bar' ), + ) + ); + + return $provider; + } + + /** + * @return array + */ + public function hiddenCategoriesDataProvider() { + + $provider = array(); + + $hidCategory = MockTitle::buildMock( __METHOD__ ); + + $hidCategory->expects( $this->any() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_CATEGORY ) ); + + $hidCategory->expects( $this->any() ) + ->method( 'getText' ) + ->will( $this->returnValue( 'Bar' ) ); + + // #0 Standard category, show hidden category + $provider[] = array( + array( + 'namespace' => NS_MAIN, + 'categories' => array( 'Foo', 'Bar' ), + 'hidCategories' => array( $hidCategory ), + 'settings' => array( + 'smwgUseCategoryHierarchy' => false, + 'smwgCategoriesAsInstances' => true, + 'smwgShowHiddenCategories' => true + ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_INST', + 'propertyValues' => array( 'Foo', 'Bar' ), + ) + ); + + // #1 Standard category, omit hidden category + $provider[] = array( + array( + 'namespace' => NS_MAIN, + 'categories' => array( 'Foo', 'Bar' ), + 'hidCategories' => array( $hidCategory ), + 'settings' => array( + 'smwgUseCategoryHierarchy' => false, + 'smwgCategoriesAsInstances' => true, + 'smwgShowHiddenCategories' => false + ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_INST', + 'propertyValues' => array( 'Foo' ), + ) + ); + + // #2 Category hierarchy or Sub-category, show hidden category + $provider[] = array( + array( + 'namespace' => NS_CATEGORY, + 'categories' => array( 'Foo', 'Bar' ), + 'hidCategories' => array( $hidCategory ), + 'settings' => array( + 'smwgUseCategoryHierarchy' => true, + 'smwgCategoriesAsInstances' => false, + 'smwgShowHiddenCategories' => true + ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_SUBC', + 'propertyValues' => array( 'Foo', 'Bar' ), + ) + ); + + // #3 Category hierarchy or Sub-category, omit hidden category + $provider[] = array( + array( + 'namespace' => NS_CATEGORY, + 'categories' => array( 'Foo', 'Bar' ), + 'hidCategories' => array( $hidCategory ), + 'settings' => array( + 'smwgUseCategoryHierarchy' => true, + 'smwgCategoriesAsInstances' => false, + 'smwgShowHiddenCategories' => false + ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_SUBC', + 'propertyValues' => array( 'Foo' ), + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/Annotator/ChainablePropertyAnnotatorTest.php b/SemanticMediaWiki/tests/phpunit/includes/Annotator/ChainablePropertyAnnotatorTest.php new file mode 100644 index 00000000..ed1d9117 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Annotator/ChainablePropertyAnnotatorTest.php @@ -0,0 +1,121 @@ +<?php + +namespace SMW\Tests\Annotator; + +use SMW\Tests\Util\SemanticDataValidator; +use SMW\Tests\Util\SemanticDataFactory; + +use SMW\Annotator\PredefinedPropertyAnnotator; +use SMW\Annotator\CategoryPropertyAnnotator; +use SMW\Annotator\SortkeyPropertyAnnotator; +use SMW\Annotator\NullPropertyAnnotator; +use SMW\DIProperty; +use SMW\Settings; +use SMW\Application; + +/** + * @covers \SMW\Annotator\PredefinedPropertyAnnotator + * @covers \SMW\Annotator\CategoryPropertyAnnotator + * @covers \SMW\Annotator\SortkeyPropertyAnnotator + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class ChainablePropertyAnnotatorTest extends \PHPUnit_Framework_TestCase { + + private $semanticDataFactory; + private $semanticDataValidator; + private $application; + + protected function setUp() { + parent::setUp(); + + $this->semanticDataFactory = new SemanticDataFactory(); + $this->semanticDataValidator = new SemanticDataValidator(); + $this->application = Application::getInstance(); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + /** + * @dataProvider annotationDataProvider + */ + public function testChainableDecoratorAnnotation( array $parameters, array $expected ) { + + $pageInfoProvider = $this->getMockBuilder( '\SMW\PageInfo' ) + ->disableOriginalConstructor() + ->getMock(); + + $pageInfoProvider->expects( $this->atLeastOnce() ) + ->method( 'getModificationDate' ) + ->will( $this->returnValue( $parameters['modificationDate'] ) ); + + $semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ ); + + $this->application->registerObject( + 'Settings', + Settings::newFromArray( $parameters['settings'] ) + ); + + $instance = new CategoryPropertyAnnotator( + new NullPropertyAnnotator( $semanticData ), + $parameters['categories'] + ); + + $instance = new SortKeyPropertyAnnotator( + $instance, + $parameters['sortkey'] + ); + + $instance = new PredefinedPropertyAnnotator( + $instance, + $pageInfoProvider + ); + + $instance->addAnnotation(); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance->getSemanticData() + ); + } + + public function annotationDataProvider() { + + $provider = array(); + + // #0 + $provider[] = array( + array( + 'modificationDate' => 1272508903, + 'categories' => array( 'Foo', 'Bar' ), + 'sortkey' => 'Lala', + 'settings' => array( + 'smwgUseCategoryHierarchy' => false, + 'smwgCategoriesAsInstances' => true, + 'smwgShowHiddenCategories' => true, + 'smwgPageSpecialProperties' => array( DIProperty::TYPE_MODIFICATION_DATE ) + ) + ), + array( + 'propertyCount' => 3, + 'propertyKeys' => array( '_INST', '_MDAT', '_SKEY' ), + 'propertyValues' => array( 'Foo', 'Bar', '2010-04-29T02:41:43', 'Lala' ), + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/Annotator/NullPropertyAnnotatorTest.php b/SemanticMediaWiki/tests/phpunit/includes/Annotator/NullPropertyAnnotatorTest.php new file mode 100644 index 00000000..5c6b928e --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Annotator/NullPropertyAnnotatorTest.php @@ -0,0 +1,54 @@ +<?php + +namespace SMW\Tests\Annotator; + +use SMW\Annotator\NullPropertyAnnotator; + +/** + * @covers \SMW\Annotator\NullPropertyAnnotator + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class NullPropertyAnnotatorTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\Annotator\NullPropertyAnnotator', + new NullPropertyAnnotator( $semanticData ) + ); + } + + public function testMethodAccess() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new NullPropertyAnnotator( $semanticData ); + + $this->assertInstanceOf( + '\SMW\SemanticData', + $instance->getSemanticData() + ); + + $this->assertInstanceOf( + '\SMW\Annotator\NullPropertyAnnotator', + $instance->addAnnotation() + ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/Annotator/PredefinedPropertyAnnotatorTest.php b/SemanticMediaWiki/tests/phpunit/includes/Annotator/PredefinedPropertyAnnotatorTest.php new file mode 100644 index 00000000..aa063c04 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Annotator/PredefinedPropertyAnnotatorTest.php @@ -0,0 +1,307 @@ +<?php + +namespace SMW\Tests\Annotator; + +use SMW\Tests\Util\SemanticDataValidator; +use SMW\Tests\Util\SemanticDataFactory; +use SMW\Tests\Util\Mock\MockTitle; + +use SMW\Annotator\PredefinedPropertyAnnotator; +use SMW\Annotator\NullPropertyAnnotator; +use SMW\DIProperty; +use SMW\DIWikiPage; +use SMW\Application; +use SMW\Settings; + +use Title; + +/** + * @covers \SMW\Annotator\PredefinedPropertyAnnotator + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class PredefinedPropertyAnnotatorTest extends \PHPUnit_Framework_TestCase { + + private $semanticDataFactory; + private $semanticDataValidator; + private $application; + + protected function setUp() { + parent::setUp(); + + $this->semanticDataFactory = new SemanticDataFactory(); + $this->semanticDataValidator = new SemanticDataValidator(); + $this->application = Application::getInstance(); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $pageInfo = $this->getMockBuilder( '\SMW\PageInfo' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new PredefinedPropertyAnnotator( + new NullPropertyAnnotator( $semanticData ), + $pageInfo + ); + + $this->assertInstanceOf( + '\SMW\Annotator\PredefinedPropertyAnnotator', + $instance + ); + } + + /** + * @dataProvider specialPropertiesDataProvider + */ + public function testAddSpecialProperties( array $parameters, array $expected ) { + + $semanticData = $this->semanticDataFactory + ->setSubject( $parameters['subject'] ) + ->newEmptySemanticData(); + + $pageInfo = $this->getMockBuilder( '\SMW\PageInfo' ) + ->disableOriginalConstructor() + ->getMock(); + + foreach ( $parameters['pageInfo'] as $method => $returnValue ) { + $pageInfo->expects( $this->any() ) + ->method( $method ) + ->will( $this->returnValue( $returnValue ) ); + } + + $this->application->registerObject( + 'Settings', + Settings::newFromArray( $parameters['settings'] ) + ); + + $instance = new PredefinedPropertyAnnotator( + new NullPropertyAnnotator( $semanticData ), + $pageInfo + ); + + $instance->addAnnotation(); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance->getSemanticData() + ); + } + + public function specialPropertiesDataProvider() { + + $provider = array(); + + #0 Unknown + $provider[] = array( + array( + 'subject' => DIWikiPage::newFromTitle( Title::newFromText( 'UNKNOWN' ) ), + 'settings' => array( + 'smwgPageSpecialProperties' => array( 'Lala', '_Lula', '-Lila', '' ) + ), + 'pageInfo' => array(), + ), + array( + 'propertyCount' => 0, + ) + ); + + #1 TYPE_MODIFICATION_DATE + $provider[] = array( + array( + 'subject' => DIWikiPage::newFromTitle( Title::newFromText( 'withModificationDate' ) ), + 'settings' => array( + 'smwgPageSpecialProperties' => array( DIProperty::TYPE_MODIFICATION_DATE ) + ), + 'pageInfo' => array( 'getModificationDate' => 1272508903 ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_MDAT', + 'propertyValues' => array( '2010-04-29T02:41:43' ), + ) + ); + + #2 TYPE_CREATION_DATE + $provider[] = array( + array( + 'subject' => DIWikiPage::newFromTitle( Title::newFromText( 'withCreationDate' ) ), + 'settings' => array( + 'smwgPageSpecialProperties' => array( DIProperty::TYPE_CREATION_DATE ) + ), + 'pageInfo' => array( 'getCreationDate' => 1272508903 ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_CDAT', + 'propertyValues' => array( '2010-04-29T02:41:43' ), + ) + ); + + #3 TYPE_NEW_PAGE + $provider[] = array( + array( + 'subject' => DIWikiPage::newFromTitle( Title::newFromText( 'NEW_PAGE_isNew' ) ), + 'settings' => array( + 'smwgPageSpecialProperties' => array( DIProperty::TYPE_NEW_PAGE ) + ), + 'pageInfo' => array( 'isNewPage' => true ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_NEWP', + 'propertyValues' => array( true ), + ) + ); + + #4 + $provider[] = array( + array( + 'subject' => DIWikiPage::newFromTitle( Title::newFromText( 'NEW_PAGE_isNotNew' ) ), + 'settings' => array( + 'smwgPageSpecialProperties' => array( DIProperty::TYPE_NEW_PAGE ) + ), + 'pageInfo' => array( 'isNewPage' => false ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_NEWP', + 'propertyValues' => array( false ), + ) + ); + + #5 TYPE_LAST_EDITOR + $userPage = MockTitle::buildMock( 'Lula' ); + + $userPage->expects( $this->any() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_USER ) ); + + $provider[] = array( + array( + 'subject' => DIWikiPage::newFromTitle( Title::newFromText( 'withLastEditor' ) ), + 'settings' => array( + 'smwgPageSpecialProperties' => array( DIProperty::TYPE_LAST_EDITOR ) + ), + 'pageInfo' => array( 'getLastEditor' => $userPage ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_LEDT', + 'propertyValues' => array( ':User:Lula' ), + ) + ); + + #6 Combined entries + $provider[] = array( + array( + 'subject' => DIWikiPage::newFromTitle( Title::newFromText( 'withCombinedEntries' ) ), + 'settings' => array( + 'smwgPageSpecialProperties' => array( '_MDAT', '_LEDT' ) + ), + 'pageInfo' => array( + 'getModificationDate' => 1272508903, + 'getLastEditor' => $userPage + ) + ), + array( + 'propertyCount' => 2, + 'propertyKeys' => array( '_MDAT', '_LEDT' ), + 'propertyValues' => array( '2010-04-29T02:41:43', ':User:Lula' ), + ) + ); + + #7 TYPE_MEDIA + $provider[] = array( + array( + 'subject' => DIWikiPage::newFromTitle( Title::newFromText( 'withMediaAsFilePage' ) ), + 'settings' => array( + 'smwgPageSpecialProperties' => array( DIProperty::TYPE_MEDIA ) + ), + 'pageInfo' => array( + 'isFilePage' => true, + 'getMediaType' => 'FooMedia' + ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_MEDIA', + 'propertyValues' => array( 'FooMedia' ), + ) + ); + + #8 + $provider[] = array( + array( + 'subject' => DIWikiPage::newFromTitle( Title::newFromText( 'withMediaNotAsFilePage' ) ), + 'settings' => array( + 'smwgPageSpecialProperties' => array( DIProperty::TYPE_MEDIA ) + ), + 'pageInfo' => array( + 'isFilePage' => false, + 'getMediaType' => 'FooMedia' + ) + ), + array( + 'propertyCount' => 0 + ) + ); + + #9 TYPE_MIME + $provider[] = array( + array( + 'subject' => DIWikiPage::newFromTitle( Title::newFromText( 'withMimeAsFilePage' ) ), + 'settings' => array( + 'smwgPageSpecialProperties' => array( DIProperty::TYPE_MIME ) + ), + 'pageInfo' => array( + 'isFilePage' => true, + 'getMimeType' => 'FooMime' + ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_MIME', + 'propertyValues' => array( 'FooMime' ), + ) + ); + + #10 + $provider[] = array( + array( + 'subject' => DIWikiPage::newFromTitle( Title::newFromText( 'withMimeNotAsFilePage' ) ), + 'settings' => array( + 'smwgPageSpecialProperties' => array( DIProperty::TYPE_MIME ) + ), + 'pageInfo' => array( + 'isFilePage' => false, + 'getMimeType' => 'FooMime' + ) + ), + array( + 'propertyCount' => 0 + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/Annotator/PropertyAnnotatorFactoryTest.php b/SemanticMediaWiki/tests/phpunit/includes/Annotator/PropertyAnnotatorFactoryTest.php new file mode 100644 index 00000000..f501f799 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Annotator/PropertyAnnotatorFactoryTest.php @@ -0,0 +1,124 @@ +<?php + +namespace SMW\Tests\Annotator; + +use SMW\Annotator\PropertyAnnotatorFactory; + +use Title; + +/** + * @covers \SMW\Annotator\PropertyAnnotatorFactory + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class PropertyAnnotatorFactoryTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\Annotator\PropertyAnnotatorFactory', + new PropertyAnnotatorFactory() + ); + } + + public function testNewPageInfoProvider() { + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new PropertyAnnotatorFactory(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\PageInfoProvider', + $instance->newPageInfoProvider( $wikiPage ) + ); + } + + public function testNewNullPropertyAnnotator() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new PropertyAnnotatorFactory(); + + $this->assertInstanceOf( + '\SMW\Annotator\NullPropertyAnnotator', + $instance->newNullPropertyAnnotator( $semanticData ) + ); + } + + public function testNewRedirectPropertyAnnotator() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $redirectTargetFinder = $this->getMockBuilder( '\SMW\MediaWiki\RedirectTargetFinder' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new PropertyAnnotatorFactory(); + + $this->assertInstanceOf( + '\SMW\Annotator\RedirectPropertyAnnotator', + $instance->newRedirectPropertyAnnotator( $semanticData, $redirectTargetFinder ) + ); + } + + public function testNewPredefinedPropertyAnnotator() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $pageInfo = $this->getMockBuilder( '\SMW\PageInfo' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new PropertyAnnotatorFactory(); + + $this->assertInstanceOf( + '\SMW\Annotator\PredefinedPropertyAnnotator', + $instance->newPredefinedPropertyAnnotator( $semanticData, $pageInfo ) + ); + } + + public function testNewSortkeyPropertyAnnotator() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new PropertyAnnotatorFactory(); + + $this->assertInstanceOf( + '\SMW\Annotator\SortkeyPropertyAnnotator', + $instance->newSortkeyPropertyAnnotator( $semanticData, 'Foo' ) + ); + } + + public function testNewCategoryPropertyAnnotator() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new PropertyAnnotatorFactory(); + + $this->assertInstanceOf( + '\SMW\Annotator\CategoryPropertyAnnotator', + $instance->newCategoryPropertyAnnotator( $semanticData, array() ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/Annotator/RedirectPropertyAnnotatorTest.php b/SemanticMediaWiki/tests/phpunit/includes/Annotator/RedirectPropertyAnnotatorTest.php new file mode 100644 index 00000000..6d80ef32 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Annotator/RedirectPropertyAnnotatorTest.php @@ -0,0 +1,126 @@ +<?php + +namespace SMW\Tests\Annotator; + +use SMW\Tests\Util\SemanticDataValidator; +use SMW\Tests\Util\SemanticDataFactory; + +use SMW\Annotator\RedirectPropertyAnnotator; +use SMW\Annotator\NullPropertyAnnotator; +use SMW\MediaWiki\RedirectTargetFinder; + +/** + * @covers \SMW\Annotator\RedirectPropertyAnnotator + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class RedirectPropertyAnnotatorTest extends \PHPUnit_Framework_TestCase { + + private $semanticDataFactory; + private $semanticDataValidator; + + protected function setUp() { + parent::setUp(); + + $this->semanticDataFactory = new SemanticDataFactory(); + $this->semanticDataValidator = new SemanticDataValidator(); + } + + protected function tearDown() { + parent::tearDown(); + } + + public function testCanConstruct() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $redirectTargetFinder = $this->getMockBuilder( '\SMW\MediaWiki\RedirectTargetFinder' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new RedirectPropertyAnnotator( + new NullPropertyAnnotator( $semanticData ), + $redirectTargetFinder + ); + + $this->assertInstanceOf( + '\SMW\Annotator\RedirectPropertyAnnotator', + $instance + ); + } + + /** + * @dataProvider redirectsDataProvider + */ + public function testAddAnnotation( array $parameter, array $expected ) { + + $semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ ); + + $redirectTargetFinder = new RedirectTargetFinder(); + + $instance = new RedirectPropertyAnnotator( + new NullPropertyAnnotator( $semanticData ), + $redirectTargetFinder->findTarget( $parameter['text'] ) + ); + + $instance->addAnnotation(); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance->getSemanticData() + ); + } + + public function redirectsDataProvider() { + + // #0 Free text + $provider[] = array( + array( 'text' => '#REDIRECT [[:Lala]]' ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_REDI', + 'propertyValues' => ':Lala' + ) + ); + + // #1 Free text + $provider[] = array( + array( 'text' => '#REDIRECT [[Lala]]' ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_REDI', + 'propertyValues' => ':Lala' + ) + ); + + + // #2 Invalid free text + $provider[] = array( + array( 'text' => '#REDIR [[:Lala]]' ), + array( + 'propertyCount' => 0, + ) + ); + + // #3 Empty + $provider[] = array( + array( 'text' => '' ), + array( + 'propertyCount' => 0, + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/Annotator/SortkeyPropertyAnnotatorTest.php b/SemanticMediaWiki/tests/phpunit/includes/Annotator/SortkeyPropertyAnnotatorTest.php new file mode 100644 index 00000000..2718105b --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Annotator/SortkeyPropertyAnnotatorTest.php @@ -0,0 +1,109 @@ +<?php + +namespace SMW\Tests\Annotator; + +use SMW\Tests\Util\SemanticDataValidator; +use SMW\Tests\Util\SemanticDataFactory; + +use SMW\Annotator\SortkeyPropertyAnnotator; +use SMW\Annotator\NullPropertyAnnotator; +use SMW\DIWikiPage; + +/** + * @covers \SMW\Annotator\SortkeyPropertyAnnotator + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SortkeyPropertyAnnotatorTest extends \PHPUnit_Framework_TestCase { + + private $semanticDataFactory; + private $semanticDataValidator; + + protected function setUp() { + parent::setUp(); + + $this->semanticDataFactory = new SemanticDataFactory(); + $this->semanticDataValidator = new SemanticDataValidator(); + } + + public function testCanConstruct() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new SortkeyPropertyAnnotator( + new NullPropertyAnnotator( $semanticData ), + 'Foo' + ); + + $this->assertInstanceOf( + '\SMW\Annotator\SortkeyPropertyAnnotator', + $instance + ); + } + + /** + * @dataProvider defaultSortDataProvider + * + * @since 1.9 + */ + public function testAddDefaultSortOnMockObserver( array $parameters, array $expected ) { + + $semanticData = $this->semanticDataFactory->setTitle( $parameters['title'] )->newEmptySemanticData(); + + $instance = new SortkeyPropertyAnnotator( + new NullPropertyAnnotator( $semanticData ), + $parameters['sort'] + ); + + $instance->addAnnotation(); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance->getSemanticData() + ); + } + + public function defaultSortDataProvider() { + + $provider = array(); + + // Sort entry + $provider[] = array( + array( + 'title' => 'Foo', + 'sort' => 'Lala' + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_SKEY', + 'propertyValues' => array( 'Lala' ), + ) + ); + + // Empty + $provider[] = array( + array( + 'title' => 'Bar', + 'sort' => '' + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_SKEY', + 'propertyValues' => array( 'Bar' ), + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/ApplicationTest.php b/SemanticMediaWiki/tests/phpunit/includes/ApplicationTest.php new file mode 100644 index 00000000..7c78087d --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/ApplicationTest.php @@ -0,0 +1,126 @@ +<?php + +namespace SMW\Tests; + +use SMW\Application; + +use Title; + +/** + * @covers \SMW\Application + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class ApplicationTest extends \PHPUnit_Framework_TestCase { + + protected function tearDown() { + Application::clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\Application', + Application::getInstance() + ); + } + + public function testCanConstructSerializerFactory() { + + $this->assertInstanceOf( + '\SMW\SerializerFactory', + Application::getInstance()->newSerializerFactory() + ); + } + + public function testCanConstructJobFactory() { + + $this->assertInstanceOf( + '\SMW\MediaWiki\Jobs\JobFactory', + Application::getInstance()->newJobFactory() + ); + } + + public function testGetStore() { + + $this->assertInstanceOf( + '\SMW\Store', + Application::getInstance()->getStore() + ); + } + + public function testGetSettings() { + + $this->assertInstanceOf( + '\SMW\Settings', + Application::getInstance()->getSettings() + ); + } + + public function testCanConstructTitleCreator() { + + $this->assertInstanceOf( + '\SMW\MediaWiki\TitleCreator', + Application::getInstance()->newTitleCreator() + ); + } + + public function testCanConstructPageCreator() { + + $this->assertInstanceOf( + '\SMW\MediaWiki\PageCreator', + Application::getInstance()->newPageCreator() + ); + } + + public function testCanConstructPropertyAnnotatorFactory() { + + $this->assertInstanceOf( + '\SMW\Annotator\PropertyAnnotatorFactory', + Application::getInstance()->newPropertyAnnotatorFactory() + ); + } + + public function testCanConstructFactboxBuilder() { + + $this->assertInstanceOf( + 'SMW\Factbox\FactboxBuilder', + Application::getInstance()->newFactboxBuilder() + ); + } + + public function testCanConstructInTextAnnotationParser() { + + $parserData = $this->getMockBuilder( '\SMW\ParserData' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\InTextAnnotationParser', + Application::getInstance()->newInTextAnnotationParser( $parserData ) + ); + } + + public function testCanConstructContentParser() { + + $title = $this->getMockBuilder( '\Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\ContentParser', + Application::getInstance()->newContentParser( $title ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/Configuration/ConfigurationTest.php b/SemanticMediaWiki/tests/phpunit/includes/Configuration/ConfigurationTest.php new file mode 100644 index 00000000..24c34490 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Configuration/ConfigurationTest.php @@ -0,0 +1,54 @@ +<?php + +namespace SMW\Tests\Configuration; + +use SMW\Configuration\Configuration; + +use ReflectionClass; + +/** + * @covers \SMW\Configuration\Configuration + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9.1 + * + * @author mwjames + */ +class ConfigurationTest extends \PHPUnit_Framework_TestCase { + + public function getClass() { + return '\SMW\Configuration\Configuration'; + } + + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), new Configuration ); + } + + public function testGet() { + + $instance = new Configuration; + + $reflector = new ReflectionClass( $this->getClass() ); + $container = $reflector->getProperty( 'container' ); + $container->setAccessible( true ); + $container->setValue( $instance, array( 'Foo' => 'Fuyu' ) ); + + $this->assertEquals( 'Fuyu', $instance->get( 'Foo' ) ); + + } + + public function testGetThrowsException() { + + $this->setExpectedException( 'InvalidArgumentException' ); + + $instance = new Configuration; + $this->assertEquals( 'Fuyu', $instance->get( 9001 ) ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/ContentParserTest.php b/SemanticMediaWiki/tests/phpunit/includes/ContentParserTest.php new file mode 100644 index 00000000..bc5b28bb --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/ContentParserTest.php @@ -0,0 +1,330 @@ +<?php + +namespace SMW\Test; + +use SMW\ContentParser; + +use TextContentHandler; +use ContentHandler; +use TextContent; +use Revision; +use Title; +use Parser; + +/** + * @covers \SMW\ContentParser + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class ContentParserTest extends SemanticMediaWikiTestCase { + + public function getClass() { + return '\SMW\ContentParser'; + } + + private function newInstance( Title $title = null, $parser = null ) { + + if ( $title === null ) { + $title = Title::newFromText( __METHOD__ ); + } + + return new ContentParser( $title, $parser ); + } + + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @depends testCanConstruct + */ + public function testCanParseOnInstance() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance()->parse() ); + } + + /** + * @depends testCanParseOnInstance + */ + public function testRunParseOnText() { + + $text = 'Foo-1-' . __METHOD__; + $expected = '<p>' . $text . "\n" . '</p>'; + + $this->assertParserOutput( $expected, $this->newInstance()->parse( $text ) ); + } + + /** + * @dataProvider titleRevisionDataProvider + * + * @since 1.9.0.2 + */ + public function testRunParseOnTitle( $setup, $expected, $withContentHandler = false ) { + + $instance = $this->getMock( $this->getClass(), + array( 'hasContentHandler' ), + array( + $setup['title'], + new Parser() + ) + ); + + $instance->expects( $this->any() ) + ->method( 'hasContentHandler' ) + ->will( $this->returnValue( $withContentHandler ) ); + + $instance->setRevision( $setup['revision'] ); + + $this->assertInstanceAfterParse( $expected, $instance->parse() ); + + } + + /** + * @dataProvider contentDataProvider + * + * @since 1.9 + */ + public function testRunParseOnTitleWithContentHandler( $setup, $expected ) { + + if ( !class_exists( 'ContentHandler') ) { + $this->markTestSkipped( + 'Skipping test due to missing class (probably MW 1.21 or lower).' + ); + } + + $this->testRunParseOnTitle( $setup, $expected, true ); + } + + protected function assertInstanceAfterParse( $expected, $instance ) { + + $this->assertInstanceOf( $this->getClass(), $instance ); + + if ( $expected['error'] ) { + return $this->assertError( $instance ); + } + + $this->assertParserOutput( $expected['text'], $instance ); + } + + protected function assertError( $instance ) { + $this->assertInternalType( 'array', $instance->getErrors() ); + $this->assertNotEmpty( $instance->getErrors() ); + } + + protected function assertParserOutput( $text, $instance ) { + + $this->assertInstanceOf( 'ParserOutput', $instance->getOutput() ); + + if ( $text !== '' ) { + + return $this->assertContains( + $text, + $instance->getOutput()->getText(), + 'Asserts that getText() returns expected text component' + ); + + } + + $this->assertEmpty( $instance->getOutput()->getText() ); + } + + /** + * @return array + */ + public function titleRevisionDataProvider() { + + $provider = array(); + + $text = 'Foo-2-' . __METHOD__; + $expected ='<p>' . $text . "\n" . '</p>'; + + // #0 Title does not exists + $title = $this->newMockBuilder()->newObject( 'Title', array( + 'getDBkey' => 'Lila', + 'exists' => false, + 'getText' => null, + 'getPageLanguage' => $this->getLanguage() + ) ); + + $provider[] = array( + array( + 'title' => $title, + 'revision' => null, + ), + array( + 'error' => true, + 'text' => '' + ) + ); + + // #1 Valid revision + $title = $this->newMockBuilder()->newObject( 'Title', array( + 'getDBkey' => 'Lula', + 'exists' => true, + 'getPageLanguage' => $this->getLanguage() + ) ); + + $revision = $this->newMockBuilder()->newObject( 'Revision', array( + 'getId' => 9001, + 'getUser' => 'Lala', + 'getText' => $text, + ) ); + + $provider[] = array( + array( + 'title' => $title, + 'revision' => $revision, + ), + array( + 'error' => false, + 'text' => $expected + ) + ); + + // #2 Null revision + $title = $this->newMockBuilder()->newObject( 'Title', array( + 'getDBkey' => 'Lula', + 'exists' => true, + 'getPageLanguage' => $this->getLanguage() + ) ); + + $revision = null; + + $provider[] = array( + array( + 'title' => $title, + 'revision' => $revision, + ), + array( + 'error' => true, + 'text' => '' + ) + ); + + return $provider; + } + + /** + * @return array + */ + public function contentDataProvider() { + + $provider = array(); + + if ( !class_exists( 'ContentHandler') ) { + $provider[] = array( array(), array() ); + return $provider; + } + + $text = 'Foo-3-' . __METHOD__; + + // #0 Title does not exists + $title = $this->newMockBuilder()->newObject( 'Title', array( + 'getDBkey' => 'Lila', + 'exists' => false, + 'getText' => null, + 'getPageLanguage' => $this->getLanguage() + ) ); + + $provider[] = array( + array( + 'title' => $title, + 'revision' => null, + ), + array( + 'error' => true, + 'text' => '' + ) + ); + + // #1 Valid revision + $title = $this->newMockBuilder()->newObject( 'Title', array( + 'getDBkey' => 'Lula', + 'exists' => true, + 'getPageLanguage' => $this->getLanguage() + ) ); + + $revision = $this->newMockBuilder()->newObject( 'Revision', array( + 'getId' => 9001, + 'getUser' => 'Lala', + 'getContent' => new TextContent( $text ) + ) ); + + $provider[] = array( + array( + 'title' => $title, + 'revision' => $revision, + ), + array( + 'error' => false, + 'text' => $text + ) + ); + + // #1 Empty content + $title = $this->newMockBuilder()->newObject( 'Title', array( + 'getDBkey' => 'Lula', + 'exists' => true, + 'getPageLanguage' => $this->getLanguage(), + 'getContentModel' => CONTENT_MODEL_WIKITEXT + ) ); + + $revision = $this->newMockBuilder()->newObject( 'Revision', array( + 'getId' => 9001, + 'getUser' => 'Lala', + 'getContent' => false, + 'getContentHandler' => new TextContentHandler() + ) ); + + $provider[] = array( + array( + 'title' => $title, + 'revision' => $revision, + ), + array( + 'error' => false, + 'text' => '' + ) + ); + + // #2 "real" revision and content + $title = $this->newTitle(); + $content = ContentHandler::makeContent( $text, $title, CONTENT_MODEL_WIKITEXT, null ); + + $revision = new Revision( + array( + 'id' => 42, + 'page' => 23, + 'title' => $title, + + 'content' => $content, + 'length' => $content->getSize(), + 'comment' => "testing", + 'minor_edit' => false, + + 'content_format' => null, + ) + ); + + $provider[] = array( + array( + 'title' => $title, + 'revision' => $revision, + ), + array( + 'error' => false, + 'text' => $text + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/CurlRequestTest.php b/SemanticMediaWiki/tests/phpunit/includes/CurlRequestTest.php new file mode 100644 index 00000000..89daff4f --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/CurlRequestTest.php @@ -0,0 +1,58 @@ +<?php + +namespace SMW\Tests; + +use SMW\CurlRequest; + +/** + * @covers \SMW\CurlRequest + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class CurlRequestTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $instance = new CurlRequest( curl_init() ); + + $this->assertInstanceOf( + '\SMW\CurlRequest', + $instance + ); + + $this->assertInstanceOf( + '\SMW\HttpRequest', + $instance + ); + } + + public function testGetLastError() { + + $instance = new CurlRequest( curl_init() ); + $this->assertInternalType( 'string', $instance->getLastError() ); + } + + public function testGetLastErrorCode() { + + $instance = new CurlRequest( curl_init() ); + $this->assertInternalType( 'integer', $instance->getLastErrorCode() ); + } + + public function testExecuteForNullUrl() { + + $instance = new CurlRequest( curl_init( null ) ); + $instance->setOption( CURLOPT_RETURNTRANSFER, true ); + + $this->assertFalse( $instance->execute() ); + $this->assertEmpty( $instance->getInfo( CURLINFO_HTTP_CODE ) ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/DataTypeRegistryTest.php b/SemanticMediaWiki/tests/phpunit/includes/DataTypeRegistryTest.php new file mode 100644 index 00000000..3064a871 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/DataTypeRegistryTest.php @@ -0,0 +1,179 @@ +<?php + +namespace SMW\Test; + +use SMW\DataTypeRegistry; +use SMWDataItem as DataItem; + +/** + * @covers \SMW\DataTypeRegistry + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class DataTypeRegistryTest extends \PHPUnit_Framework_TestCase { + + public function testGetInstance() { + $instance = DataTypeRegistry::getInstance(); + + $this->assertInstanceOf( + '\SMW\DataTypeRegistry', + $instance + ); + + $this->assertTrue( + DataTypeRegistry::getInstance() === $instance, + 'Asserts that getInstance() returns a static instance' + ); + + DataTypeRegistry::clear(); + + $this->assertTrue( + DataTypeRegistry::getInstance() !== $instance, + 'Asserts that instance has been reset' + ); + } + + /** + * @since 1.9 + */ + public function testRegisterDatatype() { + $this->assertNull( + DataTypeRegistry::getInstance()->getDataTypeClassById( '_foo' ), + 'Asserts that prior registration getDataTypeClassById() returns null' + ); + + DataTypeRegistry::getInstance()->registerDataType( '_foo', '\SMW\FooValue', DataItem::TYPE_NOTYPE, 'FooValue' ); + + $this->assertEquals( + '\SMW\FooValue', + DataTypeRegistry::getInstance()->getDataTypeClassById( '_foo' ), + 'Asserts that getDataTypeClassById() returns the registered class' + ); + + $this->assertEquals( + DataItem::TYPE_NOTYPE, + DataTypeRegistry::getInstance()->getDataItemId( '_foo' ), + 'Asserts that getDataItemId() returns the registered DataItem type' + ); + + $this->assertEquals( + 'FooValue', + DataTypeRegistry::getInstance()->findTypeLabel( '_foo' ), + 'Asserts that findTypeLabel() returns the registered label' + ); + + $this->assertEmpty( + DataTypeRegistry::getInstance()->findTypeLabel( 'FooNoLabel' ), + 'Asserts that findTypeLabel() returns an empty label' + ); + + $this->assertEquals( + DataItem::TYPE_NOTYPE, + DataTypeRegistry::getInstance()->getDataItemId( 'FooBar' ), + 'Asserts TYPE_NOTYPE is returned for non-registered type' + ); + } + + /** + * @since 1.9 + */ + public function testRegisterDatatypeIdAndAlias() { + $this->assertEmpty( + DataTypeRegistry::getInstance()->findTypeId( 'FooBar' ), + 'Asserts that findTypeID returns empty label' + ); + + DataTypeRegistry::getInstance()->registerDataTypeAlias( '_foo', 'FooBar' ); + + $this->assertTrue( + DataTypeRegistry::getInstance()->isKnownTypeId( '_foo' ) + ); + + $this->assertEquals( + '_foo', + DataTypeRegistry::getInstance()->findTypeId( 'FooBar' ), + 'Asserts that findTypeID returns the registered alias label' + ); + } + + public function testGetDefaultDataItemTypeIdForValidDataItemType() { + $this->assertInternalType( + 'string', + DataTypeRegistry::getInstance()->getDefaultDataItemTypeId( 1 ) + ); + } + + public function testGetDefaultDataItemTypeIdForInvalidDataItemType() { + $this->assertNull( + DataTypeRegistry::getInstance()->getDefaultDataItemTypeId( 9999 ) + ); + } + + public function testTypeIdAndLabelAsLanguageIndependantInvocation() { + $instance = new DataTypeRegistry( + array( '_wpg' => 'Page' ), + array( 'URI' => '_uri' ) + ); + + $this->assertEquals( + '_wpg', + $instance->findTypeId( 'Page' ), + 'Asserts that findTypeID returns empty label' + ); + + $this->assertEquals( + array( '_wpg' => 'Page' ), + $instance->getKnownTypeLabels(), + 'Asserts that getKnownTypeLabels returns an array' + ); + } + + public function testLookupByLabelIsCaseInsensitive() { + $caseVariants = array( + 'page', + 'Page', + 'PAGE', + 'pAgE', + ); + + foreach ( $caseVariants as $caseVariant ) { + $this->assertRegistryFindsIdForLabels( $caseVariant, $caseVariants ); + $this->assertRegistryFindsIdForAliases( $caseVariant, $caseVariants ); + } + } + + protected function assertRegistryFindsIdForLabels( $inputLabel, array $equivalentLabels ) { + $id = '_wpg'; + + $registry = new DataTypeRegistry( + array(), + array( $inputLabel => $id ) + ); + + foreach ( $equivalentLabels as $caseVariant ) { + $this->assertEquals( $id, $registry->findTypeId( $caseVariant ) ); + } + } + + protected function assertRegistryFindsIdForAliases( $inputLabel, array $equivalentLabels ) { + $id = '_wpg'; + + $registry = new DataTypeRegistry( + array( $id => $inputLabel ), + array() + ); + + foreach ( $equivalentLabels as $caseVariant ) { + $this->assertEquals( $id, $registry->findTypeId( $caseVariant ) ); + } + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/DataValueFactoryTest.php b/SemanticMediaWiki/tests/phpunit/includes/DataValueFactoryTest.php new file mode 100644 index 00000000..7025b494 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/DataValueFactoryTest.php @@ -0,0 +1,385 @@ +<?php + +namespace SMW\Test; + +use SMW\DataValueFactory; +use SMWDataItem; +use SMWPropertyValue; + +/** + * @covers \SMW\DataValueFactory + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class DataValueFactoryTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\DataValueFactory'; + } + + /** + * @since 1.9 + */ + public function testGetInstance() { + $this->assertInstanceOf( $this->getClass(), DataValueFactory::getInstance() ); + } + + /** + * @dataProvider dataItemIdDataProvider + * + * @since 1.9 + */ + public function testGetDataItemId( $typeId, $expectedId ) { + $this->assertEquals( $expectedId, DataValueFactory::getDataItemId( $typeId ) ); + } + + /** + * @dataProvider typeIdValueDataProvider + * + * @since 1.9 + */ + public function testNewTypeIdValue( $typeId, $value, $expectedValue, $expectedInstance ) { + + $dataValue = DataValueFactory::getInstance()->newTypeIdValue( $typeId, $value ); + $this->assertInstanceOf( $expectedInstance , $dataValue ); + + if ( $dataValue->getErrors() === array() ){ + $this->assertEquals( $expectedValue, $dataValue->getWikiValue() ); + } else { + $this->assertInternalType( 'array', $dataValue->getErrors() ); + } + + } + + /** + * @dataProvider propertyObjectValueDataProvider + * + * @since 1.9 + */ + public function testNewPropertyObjectValue( $propertyName, $value, $expectedValue, $expectedInstance ) { + + $propertyDV = SMWPropertyValue::makeUserProperty( $propertyName ); + $propertyDI = $propertyDV->getDataItem(); + + $dataValue = DataValueFactory::getInstance()->newPropertyObjectValue( $propertyDI, $value ); + + // Check the returned instance + $this->assertInstanceOf( $expectedInstance , $dataValue ); + + if ( $dataValue->getErrors() === array() ){ + $this->assertInstanceOf( 'SMWDIProperty', $dataValue->getProperty() ); + $this->assertContains( $propertyName, $dataValue->getProperty()->getLabel() ); + if ( $dataValue->getDataItem()->getDIType() === SMWDataItem::TYPE_WIKIPAGE ){ + $this->assertEquals( $expectedValue, $dataValue->getWikiValue() ); + } + } else { + $this->assertInternalType( 'array', $dataValue->getErrors() ); + } + + // Check interface parameters + $dataValue = DataValueFactory::getInstance()->newPropertyObjectValue( + $propertyDI, + $value, + $this->newRandomString(), + $this->newSubject() + ); + + $this->assertInstanceOf( $expectedInstance , $dataValue ); + } + + /** + * @dataProvider propertyValueDataProvider + * + * @since 1.9 + */ + public function testAddPropertyValue( $propertyName, $value, $expectedValue, $expectedInstance ) { + + $dataValue = DataValueFactory::getInstance()->newPropertyValue( $propertyName, $value ); + + // Check the returned instance + $this->assertInstanceOf( $expectedInstance , $dataValue ); + + if ( $dataValue->getErrors() === array() ){ + $this->assertInstanceOf( 'SMWDIProperty', $dataValue->getProperty() ); + $this->assertContains( $propertyName, $dataValue->getProperty()->getLabel() ); + if ( $dataValue->getDataItem()->getDIType() === SMWDataItem::TYPE_WIKIPAGE ){ + $this->assertEquals( $expectedValue, $dataValue->getWikiValue() ); + } + } else { + $this->assertInternalType( 'array', $dataValue->getErrors() ); + } + + // Check interface parameters + $dataValue = DataValueFactory::getInstance()->newPropertyValue( + $propertyName, + $value, + $this->newRandomString(), + $this->newSubject() + ); + + $this->assertInstanceOf( $expectedInstance , $dataValue ); + } + + /** + * @dataProvider findTypeIdDataProvider + * + * @since 1.9 + */ + public function testFindTypeID( $typeId, $expectedId ) { + $this->assertEquals( $expectedId, DataValueFactory::findTypeID( $typeId ) ); + } + + /** + * @dataProvider findTypeIdDataProvider + * + * @since 1.9 + */ + public function testFindTypeLabel( $textId, $id ) { + + $textId = $textId === 'String' ? 'Text' : $textId; + + $this->assertEquals( + $textId, + DataValueFactory::findTypeLabel( $id ), + 'Asserts that findTypeLabel() returns a user label' + ); + + } + + /** + * @since 1.9 + */ + public function testGetKnownTypeLabels() { + + $this->assertInternalType( + 'array', + DataValueFactory::getKnownTypeLabels(), + 'Asserts that getKnownTypeLabels() returns an array' + ); + + } + + /** + * @since 1.9 + */ + public function testRegisterDatatype() { + + DataValueFactory::registerDatatype( '_foo', '\SMW\FooValue', SMWDataItem::TYPE_NOTYPE, 'FooValue' ); + + $this->assertEquals( + 'FooValue', + DataValueFactory::findTypeLabel( '_foo' ), + 'Asserts that findTypeLabel() returns the registered label' + ); + + DataValueFactory::getInstance()->registerDatatype( '_foo', '\SMW\FooValue', SMWDataItem::TYPE_NOTYPE, 'FooValue' ); + + $this->assertEquals( + 'FooValue', + DataValueFactory::getInstance()->findTypeLabel( '_foo' ), + 'Asserts that findTypeLabel() returns the registered label' + ); + + } + + /** + * @since 1.9 + */ + public function testRegisterDatatypeAlias() { + + DataValueFactory::registerDatatypeAlias( '_foo', 'Bar' ); + + $this->assertEquals( + '_foo', + DataValueFactory::findTypeID( 'Bar' ), + 'Asserts that registerDatatypeAlias() registered an alias' + ); + + DataValueFactory::getInstance()->registerDatatypeAlias( '_foo', 'Bar' ); + + $this->assertEquals( + '_foo', + DataValueFactory::getInstance()->findTypeID( 'Bar' ), + 'Asserts that registerDatatypeAlias() registered an alias' + ); + } + + /** + * @dataProvider newDataItemValueDataProvider + * + * @since 1.9 + */ + public function testNewDataItemValue( $setup ) { + + $dataValue = DataValueFactory::getInstance()->newDataItemValue( $setup['dataItem'], $setup['property'], $setup['caption'] ); + + $this->assertInstanceOf( + 'SMWDataValue', + $dataValue, + 'Asserts that newDataItemValue() yields a SMWDatavalue' + ); + + } + + /** + * @return array + */ + public function newDataItemValueDataProvider() { + + $provider = array(); + + $dataItem = $this->newMockBuilder()->newObject( 'DIWikiPage' ); + $property = $this->newMockBuilder()->newObject( 'DIProperty' ); + + // #0 + $provider[] = array( + array( + 'dataItem' => $dataItem, + 'property' => null, + 'caption' => false + ) + ); + + // #0 + $provider[] = array( + array( + 'dataItem' => $dataItem, + 'property' => $property, + 'caption' => false + ) + ); + + // #1 + $provider[] = array( + array( + 'dataItem' => $dataItem, + 'property' => null, + 'caption' => 'Foo' + ) + ); + + // #2 + $provider[] = array( + array( + 'dataItem' => $dataItem, + 'property' => $property, + 'caption' => 'Bar' + ) + ); + + return $provider; + } + + /** + * @return array + */ + public function findTypeIdDataProvider() { + return array( + array( 'URL' , '_uri' ), // #0 + array( 'Page' , '_wpg' ), // #1 + array( 'String' , '_txt' ), // #2 + array( 'Text' , '_txt' ), // #3 + array( 'Number' , '_num' ), // #4 + array( 'Quantity' , '_qty' ), // #5 + array( 'Date' , '_dat' ), // #6 + array( 'Email' , '_ema' ), // #7 + array( '' , '' ), // #8 + ); + } + + /** + * @return array + */ + public function dataItemIdDataProvider() { + return array( + array( '_txt' , SMWDataItem::TYPE_BLOB ), // #0 + array( '_wpg' , SMWDataItem::TYPE_WIKIPAGE ), // #1 + array( '_num' , SMWDataItem::TYPE_NUMBER ), // #2 + array( '_dat' , SMWDataItem::TYPE_TIME ), // #3 + array( '_uri' , SMWDataItem::TYPE_URI ), // #4 + array( '_foo' , SMWDataItem::TYPE_NOTYPE ), // #5 + ); + } + + /** + * @return array + */ + public function typeIdValueDataProvider() { + return array( + array( '_txt' , 'Bar' , 'Bar' , 'SMWStringValue' ), // #0 + array( '_txt' , 'Bar[[ Foo ]]' , 'Bar[[ Foo ]]' , 'SMWStringValue' ), // #1 + array( '_txt' , '9001' , '9001' , 'SMWStringValue' ), // #2 + array( '_txt' , 1001 , '1001' , 'SMWStringValue' ), // #3 + array( '_txt' , '-%&$*' , '-%&$*' , 'SMWStringValue' ), // #4 + array( '_txt' , '_Bar' , '_Bar' , 'SMWStringValue' ), // #5 + array( '_txt' , 'bar' , 'bar' , 'SMWStringValue' ), // #6 + array( '-_txt' , 'Bar' , 'Bar' , 'SMWErrorValue' ), // #7 + + array( '_wpg' , 'Bar' , 'Bar' , 'SMWWikiPageValue' ), // #8 + array( '_wpg' , 'Bar' , 'Bar' , 'SMWWikiPageValue' ), // #9 + array( '_wpg' , 'Bar[[ Foo ]]' , 'Bar[[ Foo ]]' , 'SMWWikiPageValue' ), // #10 + array( '_wpg' , '9001' , '9001' , 'SMWWikiPageValue' ), // #11 + array( '_wpg' , 1001 , '1001' , 'SMWWikiPageValue' ), // #12 + array( '_wpg' , '-%&$*' , '-%&$*' , 'SMWWikiPageValue' ), // #13 + array( '_wpg' , '_Bar' , 'Bar' , 'SMWWikiPageValue' ), // #14 + array( '_wpg' , 'bar' , 'Bar' , 'SMWWikiPageValue' ), // #15 + array( '-_wpg' , 'Bar' , 'Bar' , 'SMWErrorValue' ), // #16 + + array( '_dat' , '1 Jan 1970' , '1 Jan 1970' , 'SMWTimeValue' ), // #0 + array( '_uri' , 'Foo' , 'Foo' , 'SMWURIValue' ), // #0 + array( '_num' , 9001 , '9,001' , 'SMWNumberValue' ), // #0 + ); + } + + /** + * @return array + */ + public function propertyValueDataProvider() { + return array( + array( 'Foo' , 'Bar' , 'Bar' , 'SMWDataValue' ), // #0 + array( 'Foo' , 'Bar[[ Foo ]]' , 'Bar[[ Foo ]]' , 'SMWDataValue' ), // #1 + array( 'Foo' , '9001' , '9001' , 'SMWDataValue' ), // #2 + array( 'Foo' , 1001 , '1001' , 'SMWDataValue' ), // #3 + array( 'Foo' , '-%&$*' , '-%&$*' , 'SMWDataValue' ), // #4 + array( 'Foo' , '_Bar' , 'Bar' , 'SMWDataValue' ), // #5 + array( 'Foo' , 'bar' , 'Bar' , 'SMWDataValue' ), // #6 + array( '-Foo' , 'Bar' , '' , 'SMWErrorValue' ), // #7 + array( '_Foo' , 'Bar' , '' , 'SMWPropertyValue' ), // #8 + ); + } + + /** + * @return array + */ + public function propertyObjectValueDataProvider() { + return array( + array( 'Foo' , 'Bar' , 'Bar' , 'SMWDataValue' ), // #0 + array( 'Foo' , 'Bar[[ Foo ]]' , 'Bar[[ Foo ]]' , 'SMWDataValue' ), // #1 + array( 'Foo' , '9001' , '9001' , 'SMWDataValue' ), // #2 + array( 'Foo' , 1001 , '1001' , 'SMWDataValue' ), // #3 + array( 'Foo' , '-%&$*' , '-%&$*' , 'SMWDataValue' ), // #4 + array( 'Foo' , '_Bar' , 'Bar' , 'SMWDataValue' ), // #5 + array( 'Foo' , 'bar' , 'Bar' , 'SMWDataValue' ), // #6 + array( '-Foo' , 'Bar' , 'Bar' , 'SMWWikiPageValue' ), // #7 + + // Will fail with "must be an instance of SMWDIProperty, instance of SMWDIError give" + // as propertyDI isn't checked therefore addPropertyValue() should be + // used as it will return a proper object + // array( '_Foo' , 'Bar' , '' , 'SMWDIProperty' ), // #8 + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/DefinesTest.php b/SemanticMediaWiki/tests/phpunit/includes/DefinesTest.php new file mode 100644 index 00000000..30f4d97e --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/DefinesTest.php @@ -0,0 +1,67 @@ +<?php + +namespace SMW\Test; + +/** + * Tests for global constants being loaded + * + * @since 1.9 + * + * @file + * @ingroup SMW + * @ingroup Test + * + * @licence GNU GPL v2+ + * @author mwjames + */ + +/** + * Tests for global constants being loaded + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class DefinesTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|boolean + */ + public function getClass() { + return false; + } + + /** + * Provides sample of constants to be tested + * + * @return array + */ + public function getConstantsDataProvider() { + return array( + array( SMW_HEADERS_SHOW, 2 ), + array( SMW_HEADERS_PLAIN, 1 ), + array( SMW_HEADERS_HIDE, 0 ), + array( SMW_OUTPUT_HTML, 1 ), + array( SMW_OUTPUT_WIKI, 2 ), + array( SMW_OUTPUT_FILE, 3 ), + array( SMW_FACTBOX_HIDDEN, 1 ), + array( SMW_FACTBOX_SPECIAL, 2 ), + array( SMW_FACTBOX_NONEMPTY, 3 ), + array( SMW_FACTBOX_SHOWN, 5 ), + ) ; + } + + /** + * Test if constants are accessible + * @dataProvider getConstantsDataProvider + * + * @param $constant + * @param $expected + */ + public function testConstants( $constant, $expected ) { + $this->assertEquals( $expected, $constant ); + } +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxBuilderTest.php b/SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxBuilderTest.php new file mode 100644 index 00000000..b37ca7a9 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxBuilderTest.php @@ -0,0 +1,64 @@ +<?php + +namespace SMW\Tests\Factbox; + +use SMW\Factbox\FactboxBuilder; + +use Title; + +/** + * @covers \SMW\Factbox\FactboxBuilder + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class FactboxBuilderTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\Factbox\FactboxBuilder', + new FactboxBuilder() + ); + } + + public function testCanConstructFactboxCache() { + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new FactboxBuilder(); + + $this->assertInstanceOf( + '\SMW\FactboxCache', + $instance->newFactboxCache( $outputPage ) + ); + } + + public function testCanConstructFactbox() { + + $parserData = $this->getMockBuilder( '\SMW\ParserData' ) + ->disableOriginalConstructor() + ->getMock(); + + $contextSource = $this->getMockBuilder( '\IContextSource' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new FactboxBuilder(); + + $this->assertInstanceOf( + '\SMW\Factbox', + $instance->newFactbox( $parserData, $contextSource ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxCacheTest.php b/SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxCacheTest.php new file mode 100644 index 00000000..06bea6ad --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxCacheTest.php @@ -0,0 +1,493 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\Mock\MockTitle; + +use SMW\FactboxCache; +use SMW\Application; +use SMW\Settings; +use SMW\DIWikiPage; +use SMW\DIProperty; + +use Language; +use ParserOutput; + +/** + * @covers \SMW\FactboxCache + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group medium + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class FactboxCacheTest extends \PHPUnit_Framework_TestCase { + + private $application; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + + $settings = Settings::newFromArray( array( + 'smwgFactboxUseCache' => true, + 'smwgCacheType' => 'hash', + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true + ) ); + + $this->application->registerObject( 'Settings', $settings ); + + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\FactboxCache', + new FactboxCache( $outputPage ) + ); + } + + public function testNewCacheId() { + + $this->assertInstanceOf( + '\SMW\CacheIdGenerator', + FactboxCache::newCacheId( 9001 ) + ); + } + + /** + * @dataProvider outputDataProvider + */ + public function testProcessAndRetrieveContent( $parameters, $expected ) { + + $this->application->getSettings()->set( + 'smwgNamespacesWithSemanticLinks', + $parameters['smwgNamespacesWithSemanticLinks'] + ); + + $this->application->getSettings()->set( + 'smwgShowFactbox', + $parameters['smwgShowFactbox'] + ); + + $this->application->registerObject( 'Store', $parameters['store'] ); + + $outputPage = $parameters['outputPage']; + + $instance = new FactboxCache( $outputPage ); + + $this->assertEmpty( $instance->retrieveContent() ); + + $instance->process( $parameters['parserOutput'] ); + $result = $outputPage->mSMWFactboxText; + + $this->assertPreProcess( + $expected, + $result, + $outputPage, + $instance + ); + + // Re-run on the same instance + $instance->process( $parameters['parserOutput'] ); + + $this->assertPostProcess( + $expected, + $result, + $outputPage, + $instance + ); + } + + public function assertPreProcess( $expected, $result, $outputPage, $instance ) { + + if ( $expected['text'] ) { + + $this->assertContains( + $expected['text'], + $result, + 'Asserts that content was altered as expected' + ); + + // Deliberately clear the outputPage property to force + // content to be retrieved from the cache + unset( $outputPage->mSMWFactboxText ); + + $this->assertTrue( + $result === $instance->retrieveContent(), + 'Asserts that cached content was retrievable' + ); + + } else { + + $this->assertNull( + $result, + 'Asserts that the result is null' + ); + } + } + + public function assertPostProcess( $expected, $result, $outputPage, $instance ) { + + $this->assertEquals( + $result, + $instance->retrieveContent(), + 'Asserts that content is being fetched from cache' + ); + + $this->assertTrue( + $result === $outputPage->mSMWFactboxText, + 'Asserts that content from the outputpage property and retrieveContent() is equal' + ); + + if ( $expected['text'] ) { + + $this->assertTrue( + $instance->isCached(), + 'Asserts that isCached() returns true' + ); + + } else { + + $this->assertFalse( + $instance->isCached(), + 'Asserts that isCached() returns false' + ); + } + } + + public function outputDataProvider() { + + $language = Language::factory( 'en' ); + + $title = MockTitle::buildMockForMainNamespace( __METHOD__ . 'mock-subject' ); + + $subject = DIWikiPage::newFromTitle( $title ); + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $semanticData->expects( $this->atLeastOnce() ) + ->method( 'getSubject' ) + ->will( $this->returnValue( $subject ) ); + + $semanticData->expects( $this->atLeastOnce() ) + ->method( 'hasVisibleProperties' ) + ->will( $this->returnValue( true ) ); + + $semanticData->expects( $this->atLeastOnce() ) + ->method( 'getPropertyValues' ) + ->will( $this->returnValue( array( DIWikiPage::newFromTitle( $title ) ) ) ); + + $semanticData->expects( $this->atLeastOnce() ) + ->method( 'getProperties' ) + ->will( $this->returnValue( array( new DIProperty( __METHOD__ . 'property' ) ) ) ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + #0 Factbox build, being visible + $title = MockTitle::buildMock( __METHOD__ . 'title-being-visible' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_MAIN ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getPageLanguage' ) + ->will( $this->returnValue( $language ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 10001 ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getLatestRevID' ) + ->will( $this->returnValue( 10001 ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( new \RequestContext() ) ); + + $provider[] = array( + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgShowFactbox' => SMW_FACTBOX_NONEMPTY, + 'outputPage' => $outputPage, + 'store' => $store, + 'parserOutput' => $this->makeParserOutput( $semanticData ) + ), + array( + 'text' => $subject->getDBKey() + ) + ); + + #1 Factbox build, being visible, using WebRequest oldid + $title = MockTitle::buildMock( __METHOD__ . 'title-with-oldid' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_MAIN ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getPageLanguage' ) + ->will( $this->returnValue( $language ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 10002 ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getLatestRevID' ) + ->will( $this->returnValue( 10002 ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $context = new \RequestContext( ); + $context->setRequest( new \FauxRequest( array( 'oldid' => 9001 ), true ) ); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( $context ) ); + + $provider[] = array( + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgShowFactbox' => SMW_FACTBOX_NONEMPTY, + 'outputPage' => $outputPage, + 'store' => $store, + 'parserOutput' => $this->makeParserOutput( $semanticData ) + ), + array( + 'text' => $subject->getDBKey() + ) + ); + + #2 Factbox is expected not to be visible + $title = MockTitle::buildMock( __METHOD__ . 'title-ns-disabled' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_MAIN ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getPageLanguage' ) + ->will( $this->returnValue( $language ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 10003 ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getLatestRevID' ) + ->will( $this->returnValue( 10003 ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( new \RequestContext() ) ); + + $provider[] = array( + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => false ), + 'smwgShowFactbox' => SMW_FACTBOX_HIDDEN, + 'outputPage' => $outputPage, + 'store' => $store, + 'parserOutput' => $this->makeParserOutput( $semanticData ) + ), + array( + 'text' => null + ) + ); + + #3 No semantic data + $title = MockTitle::buildMock( __METHOD__ . 'title-empty-semanticdata' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_MAIN ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getPageLanguage' ) + ->will( $this->returnValue( $language ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 10004 ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getLatestRevID' ) + ->will( $this->returnValue( 10004 ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( new \RequestContext() ) ); + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $semanticData->expects( $this->atLeastOnce() ) + ->method( 'isEmpty' ) + ->will( $this->returnValue( true ) ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $store->expects( $this->atLeastOnce() ) + ->method( 'getSemanticData' ) + ->will( $this->returnValue( $semanticData ) ); + + $provider[] = array( + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgShowFactbox' => SMW_FACTBOX_NONEMPTY, + 'outputPage' => $outputPage, + 'store' => $store, + 'parserOutput' => $this->makeParserOutput( null ), + ), + array( + 'text' => null + ) + ); + + // #4 SpecialPage + $title = MockTitle::buildMock( __METHOD__ . 'title-specialpage' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_MAIN ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isSpecialPage' ) + ->will( $this->returnValue( true ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( new \RequestContext() ) ); + + $provider[] = array( + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgShowFactbox' => SMW_FACTBOX_NONEMPTY, + 'outputPage' => $outputPage, + 'store' => $store, + 'parserOutput' => $this->makeParserOutput( null ), + ), + array( + 'text' => '' + ) + ); + + // #5 isDeleted + $title = MockTitle::buildMock( __METHOD__ . 'title-isDeleted' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_MAIN ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isDeleted' ) + ->will( $this->returnValue( true ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( new \RequestContext() ) ); + + $provider[] = array( + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgShowFactbox' => SMW_FACTBOX_NONEMPTY, + 'outputPage' => $outputPage, + 'store' => $store, + 'parserOutput' => $this->makeParserOutput( null ), + ), + array( + 'text' => '' + ) + ); + + return $provider; + } + + protected function makeParserOutput( $semanticData ) { + + $parserOutput = new ParserOutput(); + + if ( method_exists( $parserOutput, 'setExtensionData' ) ) { + $parserOutput->setExtensionData( 'smwdata', $semanticData ); + } else { + $parserOutput->mSMWData = $semanticData; + } + + return $parserOutput; + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxMagicWordsTest.php b/SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxMagicWordsTest.php new file mode 100644 index 00000000..e0993c8a --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxMagicWordsTest.php @@ -0,0 +1,199 @@ +<?php + +namespace SMW\Test; + +use SMW\ContentProcessor; +use SMW\ParserData; +use SMW\Settings; +use SMW\Factbox; +use SMW\Application; + +use ParserOutput; +use Title; + +/** + * @covers \SMW\Factbox + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class FactboxMagicWordsTest extends SemanticMediaWikiTestCase { + + /** + * @return string + */ + public function getClass() { + return '\SMW\Factbox'; + } + + /** + * @since 1.9 + * + * @return Factbox + */ + private function newInstance( ParserData $parserData = null, Settings $settings = null, $context = null ) { + + $mockStore = $this->newMockBuilder()->newObject( 'Store' ); + $context->setTitle( $parserData->getTitle() ); + + return new Factbox( $mockStore, $parserData, $settings, $context ); + } + + /** + * @dataProvider textDataProvider + * + * @since 1.9 + */ + public function testMagicWordsFromParserOutputExtension( $text, array $expected ) { + + $title = $this->newTitle(); + $parserOutput = new ParserOutput(); + $settings = Settings::newFromArray( array( + 'smwgNamespacesWithSemanticLinks' => array( $title->getNamespace() => true ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + ) + ); + + Application::getInstance()->registerObject( 'Settings', $settings ); + + $parserData = new ParserData( $title, $parserOutput ); + + $inTextAnnotationParser = Application::getInstance()->newInTextAnnotationParser( $parserData ); + $inTextAnnotationParser->parse( $text ); + + $this->assertEquals( + $expected['magicWords'], + $this->getMagicwords( $parserOutput ) + ); + + Application::clear(); + } + + /** + * @dataProvider textDataProvider + * + * @since 1.9 + */ + public function testGetMagicWords( $text, array $expected ) { + + $title = $this->newTitle(); + $settings = $this->newSettings( array( + 'smwgShowFactboxEdit' => SMW_FACTBOX_HIDDEN, + 'smwgShowFactbox' => SMW_FACTBOX_HIDDEN + ) + ); + + // Simulated preview context for when it is expected + if ( isset( $expected['preview'] ) && $expected['preview'] ) { + $context = $this->newContext( array( 'wpPreview' => true ) ); + $context->setTitle( $title ); + } else { + $context = $this->newContext(); + $context->setTitle( $title ); + } + + $mockParserOutput = $this->newMockBuilder()->newObject( 'ParserOutput', array( + 'getExtensionData' => $expected['magicWords'] + ) ); + + // MW 1.19, 1.20 + $mockParserOutput->mSMWMagicWords = $expected['magicWords']; + + $instance = $this->newInstance( + new ParserData( $title, $mockParserOutput ), + $settings, + $context + ); + + $reflector = $this->newReflector(); + $magic = $reflector->getMethod( 'getMagicWords' ); + $magic->setAccessible( true ); + + $result = $magic->invoke( $instance ); + $this->assertInternalType( 'integer', $result ); + $this->assertEquals( $expected['constants'], $result ); + + } + + /** + * @return array + */ + public function textDataProvider() { + + $provider = array(); + + // #0 __NOFACTBOX__, this test should not generate a factbox output + $provider[] = array( + 'Lorem ipsum dolor sit amet consectetuer auctor at quis' . + ' [[Foo::dictumst cursus]]. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[Bar::tincidunt semper]] facilisi dolor Aenean. Ut' . + ' __NOFACTBOX__ ', + array( + 'magicWords' => array( 'SMW_NOFACTBOX' ), + 'constants' => SMW_FACTBOX_HIDDEN, + 'textOutput' => '' + ) + ); + + // #1 __SHOWFACTBOX__, this test should generate a factbox output + $provider[] = array( + 'Lorem ipsum dolor sit amet consectetuer auctor at quis' . + ' [[Foo::dictumst cursus]]. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[Bar::tincidunt semper]] facilisi dolor Aenean. Ut' . + ' __SHOWFACTBOX__', + array( + 'magicWords' => array( 'SMW_SHOWFACTBOX' ), + 'constants' => SMW_FACTBOX_NONEMPTY, + 'textOutput' => 'smwfactboxhead' // lazy check because we use assertContains + ) + ); + + // #2 empty + $provider[] = array( + 'Lorem ipsum dolor sit amet consectetuer auctor at quis' . + ' [[Foo::dictumst cursus]]. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[Bar::tincidunt semper]] facilisi dolor Aenean. Ut', + array( + 'magicWords' => array(), + 'constants' => SMW_FACTBOX_HIDDEN, + 'textOutput' => '' + ) + ); + + // #3 empty + preview option + $provider[] = array( + 'Lorem ipsum dolor sit amet consectetuer auctor at quis' . + ' [[Foo::dictumst cursus]]. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[Bar::tincidunt semper]] facilisi dolor Aenean. Ut', + array( + 'magicWords' => array(), + 'preview' => true, + 'constants' => SMW_FACTBOX_HIDDEN, + 'textOutput' => '' + ) + ); + + return $provider; + } + + /** + * @return array + */ + protected function getMagicwords( $parserOutput ) { + + if ( method_exists( $parserOutput, 'getExtensionData' ) ) { + return $parserOutput->getExtensionData( 'smwmagicwords' ); + } + + return $parserOutput->mSMWMagicWords; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxTest.php b/SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxTest.php new file mode 100644 index 00000000..cd632266 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxTest.php @@ -0,0 +1,498 @@ +<?php + +namespace SMW\Test; + +use SMW\DataValueFactory; +use SMW\TableFormatter; +use SMW\ParserData; +use SMW\Factbox; +use SMW\Settings; +use SMW\DIProperty; + +use ParserOutput; +use Title; + +/** + * @covers \SMW\Factbox + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class FactboxTest extends ParserTestCase { + + /** + * @return string + */ + public function getClass() { + return '\SMW\Factbox'; + } + + /** + * @since 1.9 + * + * @return Factbox + */ + private function newInstance( ParserData $parserData = null, Settings $settings = null, $context = null ) { + + if ( $parserData === null ) { + $parserData = $this->newParserData( $this->newTitle(), $this->newParserOutput() ); + } + + if ( $settings === null ) { + $settings = $this->newSettings(); + } + + if ( $context === null ) { + $context = $this->newContext(); + } + + $mockStore = $this->newMockBuilder()->newObject( 'Store' ); + $context->setTitle( $parserData->getTitle() ); + + return new Factbox( $mockStore, $parserData, $settings, $context ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * Use a mock/stub object to verify the return value to getContent and + * isolate the method from other dependencies during test + * + * @since 1.9 + */ + public function testGetContent() { + + $text = __METHOD__; + $title = $this->newTitle(); + + $context = $this->newContext(); + $context->setTitle( $title ); + + // Build Factbox stub object to encapsulate the method + // without the need for other dependencies to occur + $factbox = $this->getMock( $this->getClass(), + array( 'fetchContent', 'getMagicWords' ), + array( + $this->newMockBuilder()->newObject( 'Store' ), + $this->newParserData( $title, $this->newParserOutput() ), + $this->newSettings(), + $context + ) + ); + + $factbox->expects( $this->any() ) + ->method( 'getMagicWords' ) + ->will( $this->returnValue( 'Lula' ) ); + + $factbox->expects( $this->any() ) + ->method( 'fetchContent' ) + ->will( $this->returnValue( $text ) ); + + // Check before execution + $this->assertFalse( $factbox->isVisible() ); + $factbox->doBuild(); + + $this->assertInternalType( 'string', $factbox->getContent() ); + $this->assertEquals( $text, $factbox->getContent() ); + + // Check after execution + $this->assertTrue( $factbox->isVisible() ); + + } + + /** + * @since 1.9 + */ + public function testGetContentRoundTrip() { + + $settings = $this->newSettings( array( + 'smwgShowFactbox' => SMW_FACTBOX_NONEMPTY + ) ); + + $mockTitle = $this->newMockBuilder()->newObject( 'Title', array( + 'getPageLanguage' => $this->getLanguage(), + ) ); + + $mockSubject = $this->newMockBuilder()->newObject( 'DIWikiPage', array( + 'getTitle' => $mockTitle, + 'getDBkey' => $mockTitle->getDBkey() + ) ); + + $mockDIProperty = $this->newMockBuilder()->newObject( 'DIProperty', array( + 'isUserDefined' => true, + 'isShown' => true, + 'getLabel' => $this->newRandomString( 10, 'property' ) + ) ); + + $mockSemanticData = $this->newMockBuilder()->newObject( 'SemanticData', array( + 'getSubject' => $mockSubject, + 'hasVisibleProperties' => true, + 'getPropertyValues' => array( $mockSubject ), + 'getProperties' => array( $mockDIProperty ) + ) ); + + $parserOutput = $this->setupParserOutput( $mockSemanticData ); + + $instance = $this->newInstance( $this->newParserData( $mockTitle , $parserOutput ), $settings ); + $result = $instance->doBuild()->getContent(); + + $this->assertInternalType( 'string', $result ); + $this->assertContains( $mockTitle->getDBkey(), $result ); + $this->assertEquals( $mockTitle, $instance->getTitle() ); + + } + + /** + * @since 1.9 + */ + public function testCreateTable() { + + $parserData = $this->newParserData( $this->newTitle(), $this->newParserOutput() ); + $instance = $this->newInstance( $parserData ); + + $reflector = $this->newReflector(); + $createTable = $reflector->getMethod( 'createTable' ); + $createTable->setAccessible( true ); + + $result = $createTable->invoke( $instance, $parserData->getData() ); + $this->assertInternalType( 'string', $result ); + + } + + /** + * @dataProvider fetchContentDataProvider + * + * @since 1.9 + */ + public function testFetchContent( $mockParserData ) { + + $instance = $this->newInstance( $mockParserData ); + $reflector = $this->newReflector(); + + $fetchContent = $reflector->getMethod( 'fetchContent' ); + $fetchContent->setAccessible( true ); + + $this->assertInternalType( 'string', $fetchContent->invoke( $instance, SMW_FACTBOX_NONEMPTY ) ); + $this->assertEmpty( $fetchContent->invoke( $instance, SMW_FACTBOX_HIDDEN ) ); + + } + + /** + * @since 1.9 + */ + public function testCreateTableOnHistoricalData() { + + $parserData = $this->newParserData( $this->newTitle(), $this->newParserOutput() ); + $instance = $this->newInstance( $parserData, null, $this->newContext( array( 'oldid' => 9001 ) ) ); + + $reflector = $this->newReflector(); + + $createTable = $reflector->getMethod( 'createTable' ); + $createTable->setAccessible( true ); + + $result = $createTable->invoke( $instance, $parserData->getData() ); + $this->assertInternalType( 'string', $result ); + + } + + /** + * @dataProvider contentDataProvider + * + * Use a mock/stub in order for getTable to return canned content to test + * fetchContent. + * + * @since 1.9 + */ + public function testGetContentDataSimulation( $setup, $expected ) { + + $mockSemanticData = $this->newMockBuilder()->newObject( 'SemanticData', array( + 'hasVisibleSpecialProperties' => $setup['hasVisibleSpecialProperties'], + 'hasVisibleProperties' => $setup['hasVisibleProperties'], + 'isEmpty' => $setup['isEmpty'] + ) ); + + $mockStore = $this->newMockBuilder()->newObject( 'Store', array( + 'getSemanticData' => $mockSemanticData, + ) ); + + $mockParserData = $this->newMockBuilder()->newObject( 'ParserData', array( + 'getSubject' => $this->newMockBuilder()->newObject( 'DIWikiPage' ), + 'getData' => null + ) ); + + // Build Factbox stub object to encapsulate the method + // without the need for other dependencies to occur + $factbox = $this->getMock( $this->getClass(), + array( 'createTable' ), + array( + $mockStore, + $mockParserData, + $this->newSettings(), + $this->newContext() + ) + ); + + $factbox->expects( $this->any() ) + ->method( 'createTable' ) + ->will( $this->returnValue( $setup['invokedContent'] ) ); + + $reflector = $this->newReflector(); + $fetchContent = $reflector->getMethod( 'fetchContent' ); + $fetchContent->setAccessible( true ); + + $this->assertInternalType( 'string', $fetchContent->invoke( $factbox ) ); + $this->assertEquals( $expected, $fetchContent->invoke( $factbox, $setup['showFactbox'] ) ); + + } + + /** + * Conditional content switcher to test combinations of + * SMW_FACTBOX_NONEMPTY and SMWSemanticData etc. + * + * @return array + */ + public function contentDataProvider() { + + $text = __METHOD__; + $provider = array(); + + $provider[] = array( + array( + 'hasVisibleSpecialProperties' => true, + 'hasVisibleProperties' => true, + 'isEmpty' => false, + 'showFactbox' => SMW_FACTBOX_NONEMPTY, + 'invokedContent' => $text, + ), + $text // expected return + ); + + $provider[] = array( + array( + 'hasVisibleSpecialProperties' => true, + 'hasVisibleProperties' => true, + 'isEmpty' => true, + 'showFactbox' => SMW_FACTBOX_NONEMPTY, + 'invokedContent' => $text, + ), + $text // expected return + ); + + $provider[] = array( + array( + 'hasVisibleSpecialProperties' => false, + 'hasVisibleProperties' => true, + 'isEmpty' => false, + 'showFactbox' => SMW_FACTBOX_SPECIAL, + 'invokedContent' => $text, + ), + '' // expected return + ); + + $provider[] = array( + array( + 'hasVisibleSpecialProperties' => false, + 'hasVisibleProperties' => false, + 'isEmpty' => false, + 'showFactbox' => SMW_FACTBOX_NONEMPTY, + 'invokedContent' => $text, + ), + '' // expected return + ); + + $provider[] = array( + array( + 'hasVisibleSpecialProperties' => true, + 'hasVisibleProperties' => false, + 'isEmpty' => false, + 'showFactbox' => SMW_FACTBOX_NONEMPTY, + 'invokedContent' => $text, + ), + '' // expected return + ); + + return $provider; + } + + /** + * Get access to the tableFormatter object in order to verify that the + * getTableHeader does return some expected content + * + * @since 1.9 + */ + public function testGetTableHeader() { + + $title = $this->newTitle(); + $reflector = $this->newReflector(); + $parserData = $this->newParserData( $title, $this->newParserOutput() ); + $instance = $this->newInstance( $parserData ); + + $mockSubject = $this->newMockBuilder()->newObject( 'DIWikiPage', array( + 'getTitle' => $title + ) ); + + $tableFormatter = $reflector->getProperty( 'tableFormatter' ); + $tableFormatter->setAccessible( true ); + $tableFormatter->setValue( $instance, new TableFormatter() ); + + $getTableHeader = $reflector->getMethod( 'getTableHeader' ); + $getTableHeader->setAccessible( true ); + $getTableHeader->invoke( $instance, $mockSubject ); + + // "smwfactboxhead"/"smwrdflink" is used for doing a lazy check on + // behalf of the invoked content + $header = $tableFormatter->getValue( $instance )->getHeaderItems(); + $this->assertTag( array( 'class' => 'smwfactboxhead' ), $header ); + $this->assertTag( array( 'class' => 'smwrdflink' ), $header ); + + } + + /** + * @dataProvider tableContentDataProvider + * + * @since 1.9 + */ + public function testGetTableContent( $test, $expected ) { + + $title = $this->newTitle(); + $reflector = $this->newReflector(); + $parserData = $this->newParserData( $title, $this->newParserOutput() ); + $instance = $this->newInstance( $parserData ); + + $mockSubject = $this->newMockBuilder()->newObject( 'DIWikiPage', array( + 'getTitle' => $title + ) ); + + $mockDIProperty = $this->newMockBuilder()->newObject( 'DIProperty', array( + 'isUserDefined' => $test['isUserDefined'], + 'isShown' => $test['isShown'], + 'getLabel' => 'Quuey' + ) ); + + $mockSemanticData = $this->newMockBuilder()->newObject( 'SemanticData', array( + 'getPropertyValues' => array( $mockSubject ), + 'getProperties' => array( $mockDIProperty ) + ) ); + + $tableFormatter = $reflector->getProperty( 'tableFormatter' ); + $tableFormatter->setAccessible( true ); + $tableFormatter->setValue( $instance, new TableFormatter() ); + + $getTableContent = $reflector->getMethod( 'getTableContent' ); + $getTableContent->setAccessible( true ); + $getTableContent->invoke( $instance, $mockSemanticData ); + + if ( $expected !== '' ) { + $this->assertTag( $expected, $tableFormatter->getValue( $instance )->getTable() ); + } else { + $this->assertEmpty( $tableFormatter->getValue( $instance )->getTable() ); + } + } + + /** + * @return array + */ + public function tableContentDataProvider() { + + $provider = array(); + + $provider[] = array( + array( + 'isShown' => true, + 'isUserDefined' => true, + ), + array( 'class' => 'smwprops' ) + ); + + $provider[] = array( + array( + 'isShown' => false, + 'isUserDefined' => true, + ), + '' + ); + + $provider[] = array( + array( + 'isShown' => true, + 'isUserDefined' => false, + ), + array( 'class' => 'smwspecs' ) + ); + + $provider[] = array( + array( + 'isShown' => false, + 'isUserDefined' => false, + ), + '' + ); + + return $provider; + } + + /** + * @return array + */ + public function fetchContentDataProvider() { + + $provider = array(); + + $mockSemanticData = $this->newMockBuilder()->newObject( 'SemanticData', array( + 'isEmpty' => false, + 'getPropertyValues' => array() + ) ); + + $mockParserData = $this->newMockBuilder()->newObject( 'ParserData', array( + 'getTitle' => $this->newTitle(), + 'getSubject' => $this->newMockBuilder()->newObject( 'DIWikiPage' ), + 'getData' => $mockSemanticData, + ) ); + + $provider[] = array( $mockParserData ); + + $mockSemanticData = $this->newMockBuilder()->newObject( 'SemanticData', array( + 'isEmpty' => false, + 'getPropertyValues' => array( new DIProperty( '_SKEY') ), + ) ); + + $mockParserData = $this->newMockBuilder()->newObject( 'ParserData', array( + 'getTitle' => $this->newTitle(), + 'getSubject' => $this->newMockBuilder()->newObject( 'DIWikiPage' ), + 'getData' => $mockSemanticData, + ) ); + + $provider[] = array( $mockParserData ); + + return $provider; + } + + /** + * @return ParserOutput + */ + protected function setupParserOutput( $semanticData ) { + + $parserOutput = $this->newParserOutput(); + + if ( method_exists( $parserOutput, 'setExtensionData' ) ) { + $parserOutput->setExtensionData( 'smwdata', $semanticData ); + } else { + $parserOutput->mSMWData = $semanticData; + } + + return $parserOutput; + + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/FormatFactoryTest.php b/SemanticMediaWiki/tests/phpunit/includes/FormatFactoryTest.php new file mode 100644 index 00000000..8995e06c --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/FormatFactoryTest.php @@ -0,0 +1,248 @@ +<?php + +namespace SMW\Tests; + +use SMW\FormatFactory; + +/** + * @covers \SMW\FormatFactory + * + * @group SMW + * @group SMWExtension + * @group SMWQueries + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class FormatFactoryTest extends \PHPUnit_Framework_TestCase { + + public function testSingleton() { + $instance = FormatFactory::singleton(); + + $this->assertInstanceOf( 'SMW\FormatFactory', $instance ); + $this->assertTrue( FormatFactory::singleton() === $instance ); + + global $smwgResultFormats, $smwgResultAliases; + + foreach ( $smwgResultFormats as $formatName => $printerClass ) { + $this->assertTrue( $instance->hasFormat( $formatName ) ); + $this->assertInstanceOf( $printerClass, $instance->getPrinter( $formatName ) ); + } + + foreach ( $smwgResultAliases as $formatName => $aliases ) { + $printerClass = $smwgResultFormats[$formatName]; + + foreach ( $aliases as $alias ) { + $this->assertTrue( $instance->hasFormat( $alias ) ); + $this->assertInstanceOf( $printerClass, $instance->getPrinter( $formatName ) ); + } + } + } + + /** + * @return FormatFactory + */ + protected function getNewInstance() { +// $reflector = new \ReflectionClass( 'SMW\FormatFactory' ); +// $constructor = $reflector->getConstructor(); +// $constructor->setAccessible( true ); +// return $constructor->invoke( $reflector ); + return new FormatFactory(); + } + + public function testRegisterFormat() { + $factory = $this->getNewInstance(); + + $factory->registerFormat( 'table', 'SMWTablePrinter' ); + $factory->registerFormat( 'list', 'SMWListResultPrinter' ); + + $this->assertArrayEquals( array( 'table', 'list' ), $factory->getFormats() ); + + $factory->registerFormat( 'table', 'SMWListResultPrinter' ); + + $printer = $factory->getPrinter( 'table' ); + + $this->assertInstanceOf( 'SMWListResultPrinter', $printer ); + } + + public function testRegisterAliases() { + $factory = $this->getNewInstance(); + + $this->assertEquals( 'foo', $factory->getCanonicalName( 'foo' ) ); + + $factory->registerAliases( 'foo', array() ); + $factory->registerAliases( 'foo', array( 'bar' ) ); + $factory->registerAliases( 'foo', array( 'baz' ) ); + $factory->registerAliases( 'ohi', array( 'there', 'o_O' ) ); + + $this->assertEquals( 'foo', $factory->getCanonicalName( 'foo' ) ); + + $this->assertEquals( 'foo', $factory->getCanonicalName( 'bar' ) ); + $this->assertEquals( 'foo', $factory->getCanonicalName( 'baz' ) ); + + $this->assertEquals( 'ohi', $factory->getCanonicalName( 'there' ) ); + $this->assertEquals( 'ohi', $factory->getCanonicalName( 'o_O' ) ); + + $factory->registerAliases( 'foo', array( 'o_O' ) ); + + $this->assertEquals( 'foo', $factory->getCanonicalName( 'o_O' ) ); + } + + public function testGetPrinter() { + $factory = FormatFactory::singleton(); + + foreach ( $factory->getFormats() as $format ) { + $printer = $factory->getPrinter( $format ); + $this->assertInstanceOf( 'SMW\QueryResultPrinter', $printer ); + } + + // In case there are no formats PHPUnit would otherwise complain here. + $this->assertTrue( true ); + } + + public function testGetFormats() { + $factory = $this->getNewInstance(); + + $this->assertInternalType( 'array', $factory->getFormats() ); + + $factory->registerFormat( 'table', 'SMWTablePrinter' ); + $factory->registerFormat( 'list', 'SMWListResultPrinter' ); + + $factory->registerAliases( 'foo', array( 'bar' ) ); + $factory->registerAliases( 'foo', array( 'baz' ) ); + $factory->registerAliases( 'ohi', array( 'there', 'o_O' ) ); + + $formats = $factory->getFormats(); + $this->assertInternalType( 'array', $formats ); + + $this->assertArrayEquals( array( 'table', 'list' ), $formats ); + } + + public function testHasFormat() { + $factory = $this->getNewInstance(); + + $this->assertFalse( $factory->hasFormat( 'ohi' ) ); + + $factory->registerFormat( 'ohi', 'SMWTablePrinter' ); + $factory->registerAliases( 'ohi', array( 'there', 'o_O' ) ); + + $this->assertTrue( $factory->hasFormat( 'ohi' ) ); + $this->assertTrue( $factory->hasFormat( 'there' ) ); + $this->assertTrue( $factory->hasFormat( 'o_O' ) ); + + $factory = FormatFactory::singleton(); + + foreach ( $factory->getFormats() as $format ) { + $this->assertTrue( $factory->hasFormat( $format ) ); + } + } + + /** + * @test FormatFactory::getPrinter + * + * @since 1.9 + */ + public function testGetPrinterException() { + $this->SetExpectedException( 'MWException' ); + + $factory = $this->getNewInstance(); + $factory->getPrinter( 'lula' ); + + $this->assertTrue( true ); + } + + /** + * @test FormatFactory::getCanonicalName + * + * @since 1.9 + */ + public function testGetCanonicalNameException() { + $this->SetExpectedException( 'MWException' ); + + $factory = $this->getNewInstance(); + $factory->getCanonicalName( 9001 ); + + $this->assertTrue( true ); + } + + /** + * @test FormatFactory::registerFormat + * @dataProvider getRegisterFormatExceptioDataProvider + * + * @since 1.9 + */ + public function testRegisterFormatException( $formatName, $class ) { + $this->SetExpectedException( 'MWException' ); + + $factory = $this->getNewInstance(); + $factory->registerFormat( $formatName, $class ); + $this->assertTrue( true ); + } + + /** + * @test FormatFactory::registerAliases + * @dataProvider getRegisterAliasesExceptioDataProvider + * + * @since 1.9 + */ + public function testRegisterAliasesException( $formatName, array $aliases ) { + $this->SetExpectedException( 'MWException' ); + + $factory = $this->getNewInstance(); + $factory->registerAliases( $formatName, $aliases ); + $this->assertTrue( true ); + } + + /** + * Register format exception data provider + * + * @return array + */ + public function getRegisterFormatExceptioDataProvider() { + return array( + array( 1001, 'Foo' ), + array( 'Foo', 9001 ), + ); + } + + /** + * Register aliases exception data provider + * + * @return array + */ + public function getRegisterAliasesExceptioDataProvider() { + return array( + array( 1001, array( 'Foo' => 'Bar' ) ), + array( 'Foo', array( 'Foo' => 9001 ) ), + ); + } + + protected function objectAssociativeSort( array &$array ) { + uasort( + $array, + function ( $a, $b ) { + return serialize( $a ) > serialize( $b ) ? 1 : -1; + } + ); + } + + protected function assertArrayEquals( array $expected, array $actual, $ordered = false, $named = false ) { + if ( !$ordered ) { + $this->objectAssociativeSort( $expected ); + $this->objectAssociativeSort( $actual ); + } + + if ( !$named ) { + $expected = array_values( $expected ); + $actual = array_values( $actual ); + } + + call_user_func_array( + array( $this, 'assertEquals' ), + array_merge( array( $expected, $actual ), array_slice( func_get_args(), 4 ) ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/GlobalFunctionsTest.php b/SemanticMediaWiki/tests/phpunit/includes/GlobalFunctionsTest.php new file mode 100644 index 00000000..f07ed52d --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/GlobalFunctionsTest.php @@ -0,0 +1,150 @@ +<?php + +namespace SMW\Test; + +/** + * Tests for the GlobalFunctions + * + * @since 1.9 + * + * @file + * @ingroup SMW + * @ingroup Test + * + * @licence GNU GPL v2+ + * @author mwjames + */ + +/** + * Tests for the GlobalFunctions + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class GlobalFunctionsTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return false; + } + + /** + * @covers ::smwfGetLinker + * @test smwfGetLinker + * + * @since 1.9 + */ + public function testSmwfGetLinker() { + $instance = smwfGetLinker(); + + $linker = class_exists( 'DummyLinker' ) ? 'DummyLinker' : 'Linker'; + $this->assertInstanceOf( $linker, $instance ); + } + + /** + * @covers ::smwfNormalTitleDBKey + * @test smwfNormalTitleDBKey + * + * @since 1.9 + */ + public function testSmwfNormalTitleDBKey() { + $result = smwfNormalTitleDBKey( ' foo bar ' ); + + // Globals are ... but it can't be invoke ... well make my day + $expected = $GLOBALS['wgCapitalLinks'] ? 'Foo_bar' : 'foo_bar'; + $this->assertEquals( $expected, $result ); + } + + /** + * @covers ::smwfHTMLtoUTF8 + * @test smwfHTMLtoUTF8 + * + * @since 1.9 + */ + public function testSmwfHTMLtoUTF8() { + $result = smwfHTMLtoUTF8( "\xc4\x88io bonas dans l'\xc3\xa9cole, Ĉio bonas dans l'école!" ); + + $expected = "Ĉio bonas dans l'école, Ĉio bonas dans l'école!"; + $this->assertEquals( $expected, $result ); + } + + /** + * @test Test if global functions are accessible + * @dataProvider getGlobalFunctions + * + * @param $function + */ + public function testGlobalFunctionsAccessibility( $function ) { + $this->assertTrue( function_exists( $function ) ); + } + + /** + * @covers ::smwfEncodeMessages + * @test smwfEncodeMessages + * @dataProvider getEncodeMessagesDataProvider + * + * @param $message + * @param $type + * @param $separator + * @param $escape + */ + public function testSmwfEncodeMessages( $message, $type, $separator, $escape ) { + $results = smwfEncodeMessages( $message ); + $this->assertFalse( is_null( $results ) ); + $this->assertTrue( is_string( $results ) ); + + $results = smwfEncodeMessages( $message, $type ); + $this->assertFalse( is_null( $results ) ); + $this->assertTrue( is_string( $results ) ); + + $results = smwfEncodeMessages( $message, $type, $separator ); + $this->assertFalse( is_null( $results ) ); + $this->assertTrue( is_string( $results ) ); + + $results = smwfEncodeMessages( $message, $type, $separator, $escape ); + $this->assertFalse( is_null( $results ) ); + $this->assertTrue( is_string( $results ) ); + } + + /** + * Provides available global functions + * + * @return array + */ + public function getGlobalFunctions() { + return array( + array( 'smwfIsSemanticsProcessed' ), + array( 'smwfNormalTitleDBKey' ), + array( 'smwfNormalTitleText' ), + array( 'smwfXMLContentEncode' ), + array( 'smwfHTMLtoUTF8' ), + array( 'smwfNumberFormat' ), + array( 'smwfEncodeMessages' ), + array( 'smwfGetStore' ), + array( 'smwfGetSparqlDatabase' ), + array( 'smwfGetLinker' ), + ) ; + } + + /** + * Provides messages + * + * @return array + */ + public function getEncodeMessagesDataProvider() { + return array( + array( array ( '', '', '' ) , '', '', true ), + array( array ( 'abc', 'ABC', '<span>Test</span>' ) , '', '', true ), + array( array ( 'abc', 'ABC', '<span>Test</span>' ) , 'warning', '', true ), + array( array ( 'abc', 'ABC', '<span>Test</span>' ) , 'info', ',', false ), + array( array ( 'abc', 'ABC', '<span>Test</span>' ) , null, ',', false ), + array( array ( 'abc', 'ABC', '<span>Test</span>' ) , '<span>Test</span>', ',', true ), + ); + } +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/HashIdGeneratorTest.php b/SemanticMediaWiki/tests/phpunit/includes/HashIdGeneratorTest.php new file mode 100644 index 00000000..1f81620e --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/HashIdGeneratorTest.php @@ -0,0 +1,79 @@ +<?php + +namespace SMW\Test; + +use SMW\HashIdGenerator; + +/** + * @covers \SMW\HashIdGenerator + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class HashIdGeneratorTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\HashIdGenerator'; + } + + /** + * @return HashIdGenerator + */ + private function newInstance( $hashable = null, $prefix = null ) { + return new HashIdGenerator( $hashable, $prefix ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testGetPrefix() { + + $instance = $this->newInstance( null, null ); + $this->assertNull( $instance->getPrefix() ); + + $prefix = $this->newRandomString(); + $instance = $this->newInstance( null, $prefix ); + $this->assertEquals( $prefix, $instance->getPrefix() ); + + // Set prefix + $prefix = $this->newRandomString(); + $instance = $this->newInstance( null, null ); + $this->assertEquals( $prefix, $instance->setPrefix( $prefix )->getPrefix() ); + + } + + /** + * @since 1.9 + */ + public function testGenerateId() { + + $hashable = $this->newRandomString(); + $prefix = $this->newRandomString(); + + $instance = $this->newInstance( $hashable, null ); + $this->assertInternalType( 'string', $instance->generateId() ); + + $instance = $this->newInstance( $hashable, $prefix ); + $this->assertInternalType( 'string', $instance->generateId() ); + $this->assertContains( $prefix, $instance->generateId() ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/HighlighterTest.php b/SemanticMediaWiki/tests/phpunit/includes/HighlighterTest.php new file mode 100644 index 00000000..a18f8df1 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/HighlighterTest.php @@ -0,0 +1,118 @@ +<?php + +namespace SMW\Test; + +use SMW\Highlighter; + +/** + * Tests for the Highlighter class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\Highlighter + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class HighlighterTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\Highlighter'; + } + + /** + * @test Highlighter::factory + * @dataProvider getTypeDataProvider + * + * @since 1.9 + * + * @param $type + */ + public function testFactory( $type ) { + $instance = Highlighter::factory( $type ); + $this->assertInstanceOf( $this->getClass(), $instance ); + } + + /** + * @test Highlighter::getTypeId + * @dataProvider getTypeDataProvider + * + * @since 1.9 + * + * @param $type + * @param $expected + */ + public function testGetTypeId( $type, $expected ) { + $results = Highlighter::getTypeId( $type ); + + $this->assertInternalType( 'integer',$results ); + $this->assertEquals( $expected, $results ); + } + + /** + * @test Highlighter::getHtml + * @dataProvider getTypeDataProvider + * + * @since 1.9 + * + * @param $type + */ + public function testGetHtml( $type ) { + + $instance = Highlighter::factory( $type ); + $title = $this->newTitle(); + + $instance->setContent( array( + 'title' => $title->getFullText() + ) ); + + // Check without caption/content set + $this->assertInternalType( 'string', $instance->getHtml() ); + + $instance->setContent( array( + 'caption' => '123', + 'content' => 'ABC', + ) ); + + // Check with caption/content set + $this->assertInternalType( 'string', $instance->getHtml() ); + } + + /** + * Provides test sample + * + * @return array + */ + public function getTypeDataProvider() { + return array( + array( '' , Highlighter::TYPE_NOTYPE ), + array( 'property', Highlighter::TYPE_PROPERTY ), + array( 'text', Highlighter::TYPE_TEXT ), + array( 'info', Highlighter::TYPE_INFO ), + array( 'help', Highlighter::TYPE_HELP ), + array( 'service', Highlighter::TYPE_SERVICE ), + array( 'quantity', Highlighter::TYPE_QUANTITY ), + array( 'note', Highlighter::TYPE_NOTE ), + array( 'warning', Highlighter::TYPE_WARNING ), + array( 'PrOpErTy', Highlighter::TYPE_PROPERTY ), + array( 'バカなテスト', Highlighter::TYPE_NOTYPE ), + array( '<span>Something that should not work</span>', Highlighter::TYPE_NOTYPE ), + array( Highlighter::TYPE_PROPERTY, Highlighter::TYPE_NOTYPE ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/InTextAnnotationParserTemplateTransclusionTest.php b/SemanticMediaWiki/tests/phpunit/includes/InTextAnnotationParserTemplateTransclusionTest.php new file mode 100644 index 00000000..acd93dd2 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/InTextAnnotationParserTemplateTransclusionTest.php @@ -0,0 +1,144 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\SemanticDataValidator; + +use SMW\InTextAnnotationParser; +use SMW\MediaWiki\MagicWordFinder; +use SMW\MediaWiki\RedirectTargetFinder; + +use SMW\Settings; +use SMW\ParserData; +use SMW\Application; + +use Title; +use ParserOutput; + +/** + * @covers \SMW\InTextAnnotationParser + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class InTextAnnotationParserTemplateTransclusionTest extends \PHPUnit_Framework_TestCase { + + private $semanticDataValidator; + private $application; + + protected function setUp() { + parent::setUp(); + + $this->semanticDataValidator = new SemanticDataValidator(); + $this->application = Application::getInstance(); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + /** + * Helper method for processing a template transclusion by simulating template + * expensions using a callback to avoid having to integrate DB read/write + * process in order to access a Template + * + * @note Part of the routine has been taken from MW's ExtraParserTest + * + * @return text + */ + private function runTemplateTransclusion( Title $title, $text, $return ) { + + $parser = new \Parser; + $options = new \ParserOptions; + $options->setTemplateCallback( function ( $title, $parser = false ) use ( $return ) { + + $text = $return; + $deps = array(); + + return array( + 'text' => $text, + 'finalTitle' => $title, + 'deps' => $deps + ); + + } ); + + return $parser->preprocess( $text, $title, $options ); + } + + /** + * @dataProvider templateDataProvider + */ + public function testPreprocessTemplateAndParse( $namespace, array $settings, $text, $tmplValue, array $expected ) { + + $parserOutput = new ParserOutput(); + $title = Title::newFromText( __METHOD__, $namespace ); + + $outputText = $this->runTemplateTransclusion( $title, $text, $tmplValue ); + + $this->application->registerObject( + 'Settings', + Settings::newFromArray( $settings ) + ); + + $parserData = new ParserData( $title, $parserOutput ); + + $instance = new InTextAnnotationParser( + $parserData, + new MagicWordFinder(), + new RedirectTargetFinder() + ); + + $instance->parse( $outputText ); + + $this->assertContains( + $expected['resultText'], + $outputText + ); + + $parserData = new ParserData( $title, $parserOutput ); + + $this->assertInstanceOf( + '\SMW\SemanticData', + $parserData->getSemanticData() + ); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $parserData->getSemanticData() + ); + } + + public function templateDataProvider() { + + $provider = array(); + + // #0 Bug 54967 + $provider[] = array( + NS_MAIN, + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + ), + '[[Foo::{{Bam}}]]', + '?bar', + array( + 'resultText' => '[[:?bar|?bar]]', + 'propertyCount' => 1, + 'propertyLabels' => array( 'Foo' ), + 'propertyValues' => array( '?bar' ) + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/InTextAnnotationParserTest.php b/SemanticMediaWiki/tests/phpunit/includes/InTextAnnotationParserTest.php new file mode 100644 index 00000000..056f0d9f --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/InTextAnnotationParserTest.php @@ -0,0 +1,405 @@ +<?php + +namespace SMW\Tests; + +use SMW\Tests\Util\SemanticDataValidator; + +use SMW\MediaWiki\MagicWordFinder; +use SMW\MediaWiki\RedirectTargetFinder; + +use SMW\InTextAnnotationParser; +use SMW\Application; +use SMW\Settings; +use SMW\ParserData; +use SMW\DIProperty; + +use Title; +use ParserOutput; +use ReflectionClass; + +/** + * @covers \SMW\InTextAnnotationParser + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class InTextAnnotationParserTest extends \PHPUnit_Framework_TestCase { + + private $semanticDataValidator; + private $application; + + protected function setUp() { + parent::setUp(); + + $this->semanticDataValidator = new SemanticDataValidator(); + $this->application = Application::getInstance(); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + /** + * @dataProvider textDataProvider + */ + public function testCanConstruct( $namespace ) { + + $parserOutput = $this->getMockBuilder( 'ParserOutput' ) + ->disableOriginalConstructor() + ->getMock(); + + $redirectTargetFinder = $this->getMockBuilder( 'SMW\MediaWiki\RedirectTargetFinder' ) + ->disableOriginalConstructor() + ->getMock(); + + $title = Title::newFromText( __METHOD__, $namespace ); + + $instance = new InTextAnnotationParser( + new ParserData( $title, $parserOutput ), + new MagicWordFinder(), + $redirectTargetFinder + ); + + $this->assertInstanceOf( + '\SMW\InTextAnnotationParser', + $instance + ); + } + + /** + * @dataProvider magicWordDataProvider + */ + public function testStripMagicWords( $namespace, $text, array $expected ) { + + $parserData = new ParserData( + Title::newFromText( __METHOD__, $namespace ), + new ParserOutput() + ); + + $magicWordFinder = new MagicWordFinder( $parserData->getOutput() ); + + $instance = new InTextAnnotationParser( + $parserData, + $magicWordFinder, + new RedirectTargetFinder() + ); + + $instance->parse( $text ); + + $this->assertEquals( + $expected, + $magicWordFinder->getMagicWords() + ); + } + + /** + * @dataProvider textDataProvider + */ + public function testTextParse( $namespace, array $settings, $text, array $expected ) { + + $parserData = new ParserData( + Title::newFromText( __METHOD__, $namespace ), + new ParserOutput() + ); + + $instance = new InTextAnnotationParser( + $parserData, + new MagicWordFinder(), + new RedirectTargetFinder() + ); + + $this->application->registerObject( + 'Settings', + Settings::newFromArray( $settings ) + ); + + $instance->parse( $text ); + + $this->assertContains( + $expected['resultText'], + $text + ); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $parserData->getSemanticData() + ); + } + + public function testRedirectAnnotation() { + + $namespace = NS_MAIN; + $text = '#REDIRECT [[:Lala]]'; + + $expected = array( + 'propertyCount' => 1, + 'property' => new DIProperty( '_REDI' ), + 'propertyValues' => ':Lala' + ); + + $settings = array( + 'smwgNamespacesWithSemanticLinks' => array( $namespace => true ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + ); + + + $this->application->registerObject( + 'Settings', + Settings::newFromArray( $settings ) + ); + + $parserData = new ParserData( + Title::newFromText( __METHOD__, $namespace ), + new ParserOutput() + ); + + $redirectTargetFinder = new RedirectTargetFinder(); + + $instance = new InTextAnnotationParser( + $parserData, + new MagicWordFinder(), + $redirectTargetFinder + ); + + $instance->parse( $text ); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $parserData->getSemanticData() + ); + } + + public function testProcessOnReflection() { + + $parserData = new ParserData( + Title::newFromText( __METHOD__ ), + new ParserOutput() + ); + + $instance = new InTextAnnotationParser( + $parserData, + new MagicWordFinder(), + new RedirectTargetFinder() + ); + + $reflector = new ReflectionClass( '\SMW\InTextAnnotationParser' ); + + $method = $reflector->getMethod( 'process' ); + $method->setAccessible( true ); + + $result = $method->invoke( $instance, array() ); + $this->assertEmpty( $result ); + + $result = $method->invoke( $instance, array( 'Test::foo', 'SMW' , 'lula' ) ); + $this->assertEmpty( $result ); + + $result = $method->invoke( $instance, array( 'Test::bar', 'SMW' , 'on' ) ); + $this->assertEmpty( $result ); + + $result = $method->invoke( $instance, array( 'Test::lula', 'SMW' , 'off' ) ); + $this->assertEmpty( $result ); + } + + public function textDataProvider() { + + $provider = array(); + + // #0 NS_MAIN; [[FooBar...]] with a different caption + $provider[] = array( + NS_MAIN, + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + ), + 'Lorem ipsum dolor sit &$% consectetuer auctor at quis' . + ' [[FooBar::dictumst|寒い]] cursus. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[Bar::tincidunt semper]] facilisi dolor Aenean. Ut' . + ' Aliquam {{volutpat}} arcu ultrices eu Ut quis [[foo::9001]] et Donec.', + array( + 'resultText' => 'Lorem ipsum dolor sit &$% consectetuer auctor at quis' . + ' [[:Dictumst|寒い]] cursus. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[:Tincidunt semper|tincidunt semper]] facilisi dolor Aenean. Ut' . + ' Aliquam {{volutpat}} arcu ultrices eu Ut quis [[:9001|9001]] et Donec.', + 'propertyCount' => 3, + 'propertyLabels' => array( 'Foo', 'Bar', 'FooBar' ), + 'propertyValues' => array( 'Dictumst', 'Tincidunt semper', '9001' ) + ) + ); + + // #1 NS_MAIN; [[FooBar...]] with a different caption and smwgLinksInValues = true + $provider[] = array( + NS_MAIN, + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgLinksInValues' => true, + 'smwgInlineErrors' => true, + ), + 'Lorem ipsum dolor sit &$% consectetuer auctor at quis' . + ' [[FooBar::dictumst|寒い]] cursus. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[Bar::[[tincidunt semper]]]] facilisi dolor Aenean. Ut' . + ' Aliquam {{volutpat}} arcu ultrices eu Ut quis [[foo::[http:://www/foo/9001] ]] et Donec.', + array( + 'resultText' => 'Lorem ipsum dolor sit &$% consectetuer auctor at quis' . + ' [[:Dictumst|寒い]] cursus. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[:Tincidunt semper|tincidunt semper]] facilisi dolor Aenean. Ut' . + ' Aliquam {{volutpat}} arcu ultrices eu Ut quis'. + ' [[:Http:://www/foo/9001|http:://www/foo/9001]] et Donec.', + 'propertyCount' => 3, + 'propertyLabels' => array( 'Foo', 'Bar', 'FooBar' ), + 'propertyValues' => array( 'Dictumst', 'Tincidunt semper', 'Http:://www/foo/9001' ) + ) + ); + + // #2 NS_MAIN, [[-FooBar...]] produces an error with inlineErrors = true + // (only check for an indication of an error in 'resultText' ) + $provider[] = array( + NS_MAIN, + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + ), + 'Lorem ipsum dolor sit &$% consectetuer auctor at quis' . + ' [[-FooBar::dictumst|重い]] cursus. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[Bar::tincidunt semper]] facilisi dolor Aenean. Ut' . + ' Aliquam {{volutpat}} arcu ultrices eu Ut quis [[foo::9001]] et Donec.', + array( + 'resultText' => 'class="smw-highlighter" data-type="4" data-state="inline"', + 'propertyCount' => 2, + 'propertyLabels' => array( 'Foo', 'Bar' ), + 'propertyValues' => array( 'Tincidunt semper', '9001' ) + ) + ); + + // #3 NS_MAIN, [[-FooBar...]] produces an error but inlineErrors = false + $provider[] = array( + NS_MAIN, + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => false, + ), + 'Lorem ipsum dolor sit &$% consectetuer auctor at quis' . + ' [[-FooBar::dictumst|軽い]] cursus. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[Bar::tincidunt semper]] facilisi dolor Aenean. Ut' . + ' Aliquam {{volutpat}} arcu ultrices eu Ut quis [[foo::9001]] et Donec.', + array( + 'resultText' => 'Lorem ipsum dolor sit &$% consectetuer auctor at quis' . + ' 軽い cursus. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[:Tincidunt semper|tincidunt semper]] facilisi dolor Aenean. Ut' . + ' Aliquam {{volutpat}} arcu ultrices eu Ut quis [[:9001|9001]] et Donec.', + 'propertyCount' => 2, + 'propertyLabels' => array( 'Foo', 'Bar' ), + 'propertyValues' => array( 'Tincidunt semper', '9001' ) + ) + ); + + // #4 NS_HELP disabled + $provider[] = array( + NS_HELP, + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_HELP => false ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + ), + 'Lorem ipsum dolor sit &$% consectetuer auctor at quis' . + ' [[FooBar::dictumst|おもろい]] cursus. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[Bar::tincidunt semper]] facilisi dolor Aenean. Ut' . + ' Aliquam {{volutpat}} arcu ultrices eu Ut quis [[foo::9001]] et Donec.', + array( + 'resultText' => 'Lorem ipsum dolor sit &$% consectetuer auctor at quis' . + ' [[:Dictumst|おもろい]] cursus. Nisl sit condimentum Quisque facilisis' . + ' Suspendisse [[:Tincidunt semper|tincidunt semper]] facilisi dolor Aenean. Ut' . + ' Aliquam {{volutpat}} arcu ultrices eu Ut quis [[:9001|9001]] et Donec.', + 'propertyCount' => 0, + 'propertyLabels' => array(), + 'propertyValues' => array() + ) + ); + + // #5 NS_HELP enabled but no properties or links at all + $provider[] = array( + NS_HELP, + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_HELP => true ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + ), + 'Lorem ipsum dolor sit &$% consectetuer auctor at quis' . + ' Suspendisse tincidunt semper facilisi dolor Aenean.', + array( + 'resultText' => 'Lorem ipsum dolor sit &$% consectetuer auctor at quis' . + ' Suspendisse tincidunt semper facilisi dolor Aenean.', + 'propertyCount' => 0, + 'propertyLabels' => array(), + 'propertyValues' => array() + ) + ); + + // #6 Bug 54967 + $provider[] = array( + NS_MAIN, + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + ), + '[[Foo::?bar]], [[Foo::Baz?]], [[Quxey::B?am]]', + array( + 'resultText' => '[[:?bar|?bar]], [[:Baz?|Baz?]], [[:B?am|B?am]]', + 'propertyCount' => 2, + 'propertyLabels' => array( 'Foo', 'Quxey' ), + 'propertyValues' => array( '?bar', 'Baz?', 'B?am' ) + ) + ); + + return $provider; + } + + /** + * @return array + */ + public function magicWordDataProvider() { + + $provider = array(); + + // #0 __NOFACTBOX__ + $provider[] = array( + NS_MAIN, + 'Lorem ipsum dolor [[Foo::dictumst cursus]] facilisi __NOFACTBOX__', + array( 'SMW_NOFACTBOX' ) + ); + + // #1 __SHOWFACTBOX__ + $provider[] = array( + NS_HELP, + 'Lorem ipsum dolor [[Foo::dictumst cursus]] facilisi __SHOWFACTBOX__', + array( 'SMW_SHOWFACTBOX' ) + ); + + // #2 __NOFACTBOX__, __SHOWFACTBOX__ + $provider[] = array( + NS_HELP, + 'Lorem ipsum dolor [[Foo::dictumst cursus]] facilisi __NOFACTBOX__ __SHOWFACTBOX__', + array( 'SMW_NOFACTBOX' ) + ); + + // #3 __SHOWFACTBOX__, __NOFACTBOX__ + $provider[] = array( + NS_HELP, + 'Lorem ipsum dolor [[Foo::dictumst cursus]] facilisi __SHOWFACTBOX__ __NOFACTBOX__', + array( 'SMW_NOFACTBOX' ) + ); + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/InfolinkTest.php b/SemanticMediaWiki/tests/phpunit/includes/InfolinkTest.php new file mode 100644 index 00000000..1bd7c226 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/InfolinkTest.php @@ -0,0 +1,90 @@ +<?php + +namespace SMW\Test; + +use SMWInfolink; + +/** + * Tests for the SMWInfolink class + * + * @since 1.9 + * + * @file + * @ingroup SMW + * @ingroup Test + * + * @licence GNU GPL v2+ + * @author mwjames + */ + +/** + * Tests for the SMWInfolink class + * @covers \SMWInfolink + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class InfolinkTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMWInfolink'; + } + + /** + * Parameter dataProvider + * + * @return array + */ + public function getParameterDataProvider() { + return array( + array( + // #0 + array( + 'format=template', + 'link=none' + ), + array( + 'format=template/link=none', + 'x=format%3Dtemplate%2Flink%3Dnone' + ) + ), + + // #1 Bug 47010 (space encoding, named args => named%20args) + array( + array( + 'format=template', + 'link=none', + 'named args=1' + ), + array( + 'format=template/link=none/named-20args=1', + 'x=format%3Dtemplate%2Flink%3Dnone%2Fnamed-20args%3D1' + ) + ), + ); + } + + /** + * @test SMWInfolink::encodeParameters + * @dataProvider getParameterDataProvider + * + * @since 1.9 + * + * @param array $params + * @param array $expectedEncode + */ + public function testEncodeParameters( array $params, array $expectedEncode ) { + $encodeResult = SMWInfolink::encodeParameters( $params, true ); + $this->assertEquals( $expectedEncode[0], $encodeResult ); + + $encodeResult = SMWInfolink::encodeParameters( $params, false ); + $this->assertEquals( $expectedEncode[1], $encodeResult ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/ApiQueryResultFormatterTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/ApiQueryResultFormatterTest.php new file mode 100644 index 00000000..1fe24d68 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/ApiQueryResultFormatterTest.php @@ -0,0 +1,345 @@ +<?php + +namespace SMW\Tests\MediaWiki\Api; + +use SMW\MediaWiki\Api\ApiQueryResultFormatter; + +use SMWQueryResult; + +use ReflectionClass; + +/** + * @covers \SMW\MediaWiki\Api\ApiQueryResultFormatter + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class ApiQueryResultFormatterTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $queryResult = $this->getMockBuilder( '\SMWQueryResult' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Api\ApiQueryResultFormatter', + new ApiQueryResultFormatter( $queryResult ) + ); + } + + public function testSetIndexedTagNameException() { + + $queryResult = $this->getMockBuilder( '\SMWQueryResult' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new ApiQueryResultFormatter( $queryResult ); + $instance->setIsRawMode( true ); + + $reflector = new ReflectionClass( '\SMW\MediaWiki\Api\ApiQueryResultFormatter' ); + $method = $reflector->getMethod( 'setIndexedTagName' ); + $method->setAccessible( true ); + + $this->setExpectedException( 'InvalidArgumentException' ); + + $this->assertTrue( $method->invoke( $instance, array(), null ) ); + } + + /** + * @dataProvider resultDataProvider + */ + public function testResultFormat( array $parameters, array $expected ) { + + $queryResult = $this->getMockBuilder( '\SMWQueryResult' ) + ->disableOriginalConstructor() + ->getMock(); + + $queryResult->expects( $this->atLeastOnce() ) + ->method( 'toArray' ) + ->will( $this->returnValue( $parameters['result'] ) ); + + $queryResult->expects( $this->atLeastOnce() ) + ->method( 'getErrors' ) + ->will( $this->returnValue( array() ) ); + + $queryResult->expects( $this->atLeastOnce() ) + ->method( 'hasFurtherResults' ) + ->will( $this->returnValue( $parameters['furtherResults'] ) ); + + $instance = new ApiQueryResultFormatter( $queryResult ); + + $instance->setIsRawMode( $parameters['rawMode'] ); + $instance->doFormat(); + + $this->assertEquals( 'query', $instance->getType() ); + + $this->assertEquals( + $expected['result'], + $instance->getResult() + ); + + $this->assertEquals( + $expected['continueOffset'], + $instance->getContinueOffset() + ); + } + + /** + * @dataProvider errorDataProvider + */ + public function testErrorFormat( array $parameters, array $expected ) { + + $queryResult = $this->getMockBuilder( '\SMWQueryResult' ) + ->disableOriginalConstructor() + ->getMock(); + + $queryResult->expects( $this->atLeastOnce() ) + ->method( 'getErrors' ) + ->will( $this->returnValue( $parameters['errors'] ) ); + + $instance = new ApiQueryResultFormatter( $queryResult ); + + $instance->setIsRawMode( $parameters['rawMode'] ); + $instance->doFormat(); + + $this->assertEquals( 'error', $instance->getType() ); + + $this->assertEquals( + $expected, + $instance->getResult() + ); + } + + public function resultDataProvider() { + + $result = array( + 'results' => array( + 'Foo' => array( + 'printouts' => array( 'lula' => array( 'lila' ) ) + ) + ), + 'printrequests' => array( 'Bar' ), + 'meta' => array( 'count' => 5, 'offset' => 5 ) + ); + + $xml = array( + 'results' => array( + array( + 'printouts' => array( + array( 'label' => 'lula', 'lila', '_element' => 'value' ), + '_element' => 'property' ) + ), + '_element' => 'subject' + ), + 'printrequests' => array( + 'Bar', + '_element' => 'printrequest' + ), + 'meta' => array( 'count' => 5, 'offset' => 5, '_element' => 'meta' ) + ); + + $provider = array(); + + // #0 Without further results + $provider[] = array( + array( + 'result' => $result, + 'rawMode' => false, + 'furtherResults' => false + ), + array( + 'result' => $result, + 'continueOffset' => false + ) + ); + + // #1 Without further results + XML + $provider[] = array( + array( + 'result' => $result, + 'rawMode' => true, + 'furtherResults' => false + ), + array( + 'result' => $xml, + 'continueOffset' => false + ) + ); + + // #2 With further results + $provider[] = array( + array( + 'result' => $result, + 'rawMode' => false, + 'furtherResults' => true + ), + array( + 'result' => $result, + 'continueOffset' => 10 + ) + ); + + // #3 With further results + XML + $provider[] = array( + array( + 'result' => $result, + 'rawMode' => true, + 'furtherResults' => true + ), + array( + 'result' => $xml, + 'continueOffset' => 10 + ) + ); + + + // #4 Extended subject data + XML + $provider[] = array( + array( + 'result' => array( + 'results' => array( + 'Foo' => array( + 'printouts' => array( + 'lula' => array( 'lila' ) ), + 'fulltext' => 'Foo' ) + ), + 'printrequests' => array( 'Bar' ), + 'meta' => array( + 'count' => 5, + 'offset' => 5 + ) + ), + 'rawMode' => true, + 'furtherResults' => true + ), + array( + 'result' => array( + 'results' => array( + array( + 'printouts' => array( + array( + 'label' => 'lula', + 'lila', '_element' => 'value' + ), '_element' => 'property' ), + 'fulltext' => 'Foo' + ), '_element' => 'subject' + ), + 'printrequests' => array( 'Bar', '_element' => 'printrequest' ), + 'meta' => array( + 'count' => 5, + 'offset' => 5, + '_element' => 'meta' + ) + ), + 'continueOffset' => 10 + ) + ); + + // #5 printouts without values + XML + $provider[] = array( + array( + 'result' => array( + 'results' => array( + 'Foo' => array( + 'printouts' => array( 'lula' ), + 'fulltext' => 'Foo' ) + ), + 'printrequests' => array( 'Bar' ), + 'meta' => array( + 'count' => 5, + 'offset' => 5 + ) + ), + 'rawMode' => true, + 'furtherResults' => true + ), + array( + 'result' => array( + 'results' => array( + array( + 'printouts' => array( '_element' => 'property' ), + 'fulltext' => 'Foo' + ), + '_element' => 'subject' + ), + 'printrequests' => array( 'Bar', '_element' => 'printrequest' ), + 'meta' => array( + 'count' => 5, + 'offset' => 5, + '_element' => 'meta' + ) + ), + 'continueOffset' => 10 + ) + ); + + // #6 empty results + XML + $provider[] = array( + array( + 'result' => array( + 'results' => array(), + 'printrequests' => array( 'Bar' ), + 'meta' => array( + 'count' => 0, + 'offset' => 0 + ) + ), + 'rawMode' => true, + 'furtherResults' => false + ), + array( + 'result' => array( + 'results' => array(), + 'printrequests' => array( 'Bar', '_element' => 'printrequest' ), + 'meta' => array( + 'count' => 0, + 'offset' => 0, + '_element' => 'meta' + ) + ), + 'continueOffset' => 0 + ) + ); + + return $provider; + } + + public function errorDataProvider() { + + $errors = array( 'Foo', 'Bar' ); + + $provider = array(); + + // #0 + $provider[] = array( + array( + 'rawMode'=> false, + 'errors' => $errors + ), + array( + 'query' => $errors + ) + ); + + // #1 + $provider[] = array( + array( + 'rawMode'=> true, + 'errors' => $errors + ), + array( + 'query' => array_merge( $errors, array( '_element' => 'info' ) ) + ) + ); + + return $provider; + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/ApiRequestParameterFormatterTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/ApiRequestParameterFormatterTest.php new file mode 100644 index 00000000..65955883 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/ApiRequestParameterFormatterTest.php @@ -0,0 +1,93 @@ +<?php + +namespace SMW\Tests\MediaWiki\Api; + +use SMW\MediaWiki\Api\ApiRequestParameterFormatter; + +use SMWQueryResult; + +/** + * @covers \SMW\MediaWiki\Api\ApiRequestParameterFormatter + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class ApiRequestParameterFormatterTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\MediaWiki\Api\ApiRequestParameterFormatter', + new ApiRequestParameterFormatter( array() ) + ); + } + + public function testGetAskArgsApiForEmptyParameter() { + + $nstance = new ApiRequestParameterFormatter( array() ); + + $this->assertEmpty( $nstance->getAskArgsApiParameter( 'conditions' ) ); + $this->assertEmpty( $nstance->getAskArgsApiParameter( 'parameters' ) ); + $this->assertEmpty( $nstance->getAskArgsApiParameter( 'printouts' ) ); + } + + /** + * @dataProvider requestArgsApiParametersDataProvider + */ + public function testGetAskArgsApiParameter( $parameters, $type, $expected ) { + + $nstance = new ApiRequestParameterFormatter( $parameters ); + + $this->assertEquals( + $expected, + $nstance->getAskArgsApiParameter( $type ) + ); + } + + /** + * @dataProvider requestAskApiParametersDataProvider + */ + public function testGetAskApiParameters( $parameters, $expected ) { + + $instance = new ApiRequestParameterFormatter( $parameters ); + $result = $instance->getAskApiParameters(); + + $this->assertInternalType( 'array', $result ); + $this->assertEquals( $expected, $result ); + } + + public function requestArgsApiParametersDataProvider() { + return array( + array( array( 'conditions' => array( 'Lala' ) ), 'conditions', '[[Lala]]' ), + array( array( 'conditions' => array( 'Lala', 'Lima' ) ), 'conditions', '[[Lala]] [[Lima]]' ), + array( array( 'parameters' => array( 'Lila' ) ), 'parameters', array() ), + array( array( 'parameters' => array( 'Lila=isFunny' ) ), 'parameters', array( 'Lila' => 'isFunny' ) ), + array( array( 'parameters' => array( 'Lila=isFunny', 'Lula=isHappy' ) ), 'parameters', array( 'Lila' => 'isFunny', 'Lula' => 'isHappy' ) ), + array( array( 'printouts' => array( '?Linda' ) ), 'printouts', array( $this->newPrintRequest( '?Linda' ) ) ), + array( array( 'printouts' => array( '?Luna', '?Mars' ) ), 'printouts', array( $this->newPrintRequest( '?Luna' ), $this->newPrintRequest( '?Mars' ) ) ), + ); + } + + public function requestAskApiParametersDataProvider() { + return array( + array( array(), array() ), + array( array( 'query' => '[[Modification date::+]]' ), array( '[[Modification date::+]]' ) ), + array( array( 'query' => '[[Modification date::+]]|?Modification date' ), array( '[[Modification date::+]]', '?Modification date' ) ), + array( array( 'query' => '[[Modification date::+]]|?Modification date|sort=desc' ), array( '[[Modification date::+]]', '?Modification date', 'sort=desc' ) ), + ); + } + + private function newPrintRequest( $printout ) { + return new \SMWPrintRequest( + \SMWPrintRequest::PRINT_PROP, + $printout, + \SMWPropertyValue::makeUserProperty( $printout ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/AskArgsTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/AskArgsTest.php new file mode 100644 index 00000000..ba3dc386 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/AskArgsTest.php @@ -0,0 +1,260 @@ +<?php + +namespace SMW\Tests\MediaWiki\Api; + +use SMW\Tests\Util\MwApiFactory; + +use SMW\MediaWiki\Api\AskArgs; +use SMW\Application; + +/** + * @covers \SMW\MediaWiki\Api\AskArgs + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-api + * @group mediawiki-api + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class AskArgsTest extends \PHPUnit_Framework_TestCase { + + private $apiFactory; + private $application; + + protected function setUp() { + parent::setUp(); + + $this->apiFactory = new MwApiFactory(); + $this->application = Application::getInstance(); + } + + protected function tearDown() { + Application::clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $instance = new AskArgs( + $this->apiFactory->newApiMain( array() ), + 'askargs' + ); + + $this->assertInstanceOf( + 'SMW\MediaWiki\Api\AskArgs', + $instance + ); + } + + /** + * @dataProvider queryDataProvider + */ + public function testExecuteOnStore( array $query, array $expected ) { + + $results = $this->apiFactory->doApiRequest( array( + 'action' => 'askargs', + 'conditions' => $query['conditions'], + 'printouts' => $query['printouts'], + 'parameters' => $query['parameters'], + ) ); + + $this->assertInternalType( 'array', $results ); + + if ( isset( $expected['error'] ) ) { + return $this->assertArrayHasKey( 'error', $results ); + } + + $this->assertEquals( + $expected, + $results['query']['printrequests'] + ); + } + + public function testExecuteOnMockStore() { + + $requestParameters = array( + 'conditions' => 'Foo::+', + 'printouts' => 'Bar', + 'parameters' => 'sort=asc' + ); + + $expected = array( + 'query-continue-offset' => 10, + 'query' => array( + 'results' => array( + 'Foo' => array( + 'printouts' => array( 'lula' => array( 'lila' ) ) + ) + ), + 'printrequests' => array( 'Bar' ), + 'meta' => array( 'count' => 5, 'offset' => 5 ) + ) + ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $store->expects( $this->atLeastOnce() ) + ->method( 'getQueryResult' ) + ->will( $this->returnCallback( array( $this, 'mockStoreQueryResultCallback' ) ) ); + + $this->application->registerObject( 'Store', $store ); + + $instance = new AskArgs( + $this->apiFactory->newApiMain( $requestParameters ), + 'askargs' + ); + + $instance->execute(); + + $result = $instance->getResultData(); + + $this->assertInternalType( 'array', $result ); + $this->assertEquals( $expected, $result ); + } + + public function mockStoreQueryResultCallback( $query ) { + + $result = ''; + + if ( $query->getQueryString() === '[[Foo::+]]' ) { + $result = array( + 'results' => array( + 'Foo' => array( + 'printouts' => array( 'lula' => array( 'lila' ) ) + ) + ), + 'printrequests' => array( 'Bar' ), + 'meta' => array( 'count' => 5, 'offset' => 5 ) + ); + } + + $queryResult = $this->getMockBuilder( '\SMWQueryResult' ) + ->disableOriginalConstructor() + ->getMock(); + + $queryResult->expects( $this->atLeastOnce() ) + ->method( 'toArray' ) + ->will( $this->returnValue( $result ) ); + + $queryResult->expects( $this->atLeastOnce() ) + ->method( 'hasFurtherResults' ) + ->will( $this->returnValue( true ) ); + + $queryResult->expects( $this->atLeastOnce() ) + ->method( 'getErrors' ) + ->will( $this->returnValue( array() ) ); + + return $queryResult; + } + + public function queryDataProvider() { + return array( + + // #0 Query producing an error result + array( + array( + 'conditions' => '[[Modification date::+]]', + 'printouts' => null, + 'parameters' => null + ), + array( + 'error' => true + ) + ), + + // #1 Query producing an error result + array( + array( + 'conditions' => '[[Modification date::+]]', + 'printouts' => null, + 'parameters' => 'limit=10' + ), + array( + 'error' => true + ) + ), + + // #2 Query producing an error result + array( + array( + 'conditions' => '[[Modification date::+]]', + 'printouts' => 'Modification date', + 'parameters' => 'limit=10' + ), + array( + 'error' => true + ) + ), + + // #3 Query producing a return result + array( + array( + 'conditions' => 'Modification date::+', + 'printouts' => null, + 'parameters' => null + ), + array( + array( + 'label'=> '', + 'typeid' => '_wpg', + 'mode' => 2, + 'format' => false + ) + ) + ), + + // #4 Query producing a return result + array( + array( + 'conditions' => 'Modification date::+', + 'printouts' => 'Modification date', + 'parameters' => null + ), + array( + array( + 'label'=> '', + 'typeid' => '_wpg', + 'mode' => 2, + 'format' => false + ), + array( + 'label'=> 'Modification date', + 'typeid' => '_dat', + 'mode' => 1, + 'format' => '' + ) + ) + ), + + // #5 Query producing a return result + array( + array( + 'conditions' => 'Modification date::+', + 'printouts' => 'Modification date', + 'parameters' => 'limit=1' + ), + array( + array( + 'label'=> '', + 'typeid' => '_wpg', + 'mode' => 2, + 'format' => false + ), + array( + 'label'=> 'Modification date', + 'typeid' => '_dat', + 'mode' => 1, + 'format' => '' + ) + ) + ), + ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/AskTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/AskTest.php new file mode 100644 index 00000000..292143b8 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/AskTest.php @@ -0,0 +1,104 @@ +<?php + +namespace SMW\Tests\MediaWiki\Api; + +use SMW\Tests\Util\MwApiFactory; + +use SMW\MediaWiki\Api\Ask; + +/** + * @covers \SMW\MediaWiki\Api\Ask + * + * @group SMW + * @group SMWExtension + * @group API + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class AskTest extends \PHPUnit_Framework_TestCase { + + private $apiFactory; + + protected function setUp() { + parent::setUp(); + + $this->apiFactory = new MwApiFactory(); + } + + public function testCanConstruct() { + + $instance = new Ask( + $this->apiFactory->newApiMain( array( 'query' => 'Foo' ) ), + 'ask' + ); + + $this->assertInstanceOf( + 'SMW\MediaWiki\Api\Ask', + $instance + ); + } + + /** + * @dataProvider sampleQueryProvider + */ + public function testExecute( array $query, array $expected ) { + + $results = $this->apiFactory->doApiRequest( array( + 'action' => 'ask', + 'query' => implode( '|', $query ) + ) ); + + $this->assertInternalType( 'array', $results ); + + // If their is no printrequests array we expect an error array + if ( isset( $results['query']['printrequests'] ) ) { + return $this->assertEquals( $expected, $results['query']['printrequests'] ); + } + + $this->assertArrayHasKey( 'error', $results ); + } + + public function sampleQueryProvider() { + + // #0 Standard query + $provider[] = array( + array( + '[[Modification date::+]]', + '?Modification date', + 'limit=10' + ), + array( + array( + 'label'=> '', + 'typeid' => '_wpg', + 'mode' => 2, + 'format' => false + ), + array( + 'label'=> 'Modification date', + 'typeid' => '_dat', + 'mode' => 1, + 'format' => '' + ) + ) + ); + + $provider[] = array( + array( + '[[Modification date::+!]]', + 'limit=3' + ), + array( + array( + 'error'=> 'foo', + ) + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/BrowseBySubjectTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/BrowseBySubjectTest.php new file mode 100644 index 00000000..c20336d5 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/BrowseBySubjectTest.php @@ -0,0 +1,144 @@ +<?php + +namespace SMW\Tests\MediaWiki\Api; + +use SMW\Tests\Util\MwApiFactory; +use SMW\Tests\Util\SemanticDataFactory; +use SMW\Tests\Util\Mock\MockTitle; + +use SMW\MediaWiki\Api\BrowseBySubject; +use SMW\Application; + +use Title; + +/** + * @covers \SMW\MediaWiki\Api\BrowseBySubject + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-api + * @group mediawiki-api + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class BrowseBySubjectTest extends \PHPUnit_Framework_TestCase { + + private $apiFactory; + private $semanticDataFactory; + private $application; + + protected function setUp() { + parent::setUp(); + + $this->apiFactory = new MwApiFactory(); + $this->semanticDataFactory = new SemanticDataFactory(); + $this->application = Application::getInstance(); + } + + protected function tearDown() { + Application::clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $instance = new BrowseBySubject( + $this->apiFactory->newApiMain( array('subject' => 'Foo' ) ), + 'browsebysubject' + ); + + $this->assertInstanceOf( + 'SMW\MediaWiki\Api\BrowseBySubject', + $instance + ); + } + + public function testExecuteOnValidSubject() { + + $expectedResultToContainArrayKeys = array( 'error' => false, 'result' => true ); + + $result = $this->apiFactory->doApiRequest( array( + 'action' => 'browsebysubject', + 'subject' => 'Main_Page' + ) ); + + $this->assertToContainArrayKeys( + $expectedResultToContainArrayKeys, + $result + ); + } + + public function testExecuteOnInvalidSubjectThrowsException() { + + $this->setExpectedException( 'Exception' ); + + $result = $this->apiFactory->doApiRequest( array( + 'action' => 'browsebysubject', + 'subject' => '{}' + ) ); + } + + public function testValidTitleRedirect() { + + $semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $store->expects( $this->atLeastOnce() ) + ->method( 'getSemanticData' ) + ->will( $this->returnValue( $semanticData ) ); + + $titleCreator = $this->getMockBuilder( '\SMW\MediaWiki\TitleCreator' ) + ->setMethods( array( 'getTitle', 'findRedirect' ) ) + ->getMock(); + + $titleCreator->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( Title::newFromText( 'Ooooooo' ) ) ); + + $titleCreator->expects( $this->atLeastOnce() ) + ->method( 'findRedirect' ) + ->will( $this->returnValue( $titleCreator ) ); + + $this->application->registerObject( 'Store', $store ); + $this->application->registerObject( 'TitleCreator', $titleCreator ); + + $expectedResultToContainArrayKeys = array( 'subject' => true, 'result' => true ); + + $instance = new BrowseBySubject( + $this->apiFactory->newApiMain( array('subject' => 'Foo' ) ), + 'browsebysubject' + ); + + $instance->getMain()->getResult()->setRawMode(); + $instance->execute(); + + $result = $instance->getResultData(); + + $this->assertToContainArrayKeys( + $expectedResultToContainArrayKeys, + $result + ); + } + + public function assertToContainArrayKeys( $setup, $result ) { + $this->assertInternalArrayStructure( $setup, $result, 'error', 'array', function( $r ) { return $r['error']; } ); + $this->assertInternalArrayStructure( $setup, $result, 'result', 'array', function( $r ) { return $r['query']; } ); + $this->assertInternalArrayStructure( $setup, $result, 'subject', 'string', function( $r ) { return $r['query']['subject']; } ); + $this->assertInternalArrayStructure( $setup, $result, 'data', 'array', function( $r ) { return $r['query']['data']; } ); + $this->assertInternalArrayStructure( $setup, $result, 'sobj', 'array', function( $r ) { return $r['query']['sobj']; } ); + } + + protected function assertInternalArrayStructure( $setup, $result, $field, $internalType, $definition ) { + if ( isset( $setup[$field] ) && $setup[$field] ) { + $this->assertInternalType( $internalType, is_callable( $definition ) ? $definition( $result ) : $definition ); + } + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/InfoTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/InfoTest.php new file mode 100644 index 00000000..45f5f7c2 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/InfoTest.php @@ -0,0 +1,152 @@ +<?php + +namespace SMW\Tests\MediaWiki\Api; + +use SMW\Tests\Util\MwApiFactory; + +use SMW\Application; +use SMW\MediaWiki\Api\Info; + +/** + * @covers \SMW\MediaWiki\Api\Info + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-api + * @group mediawiki-api + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class InfoTest extends \PHPUnit_Framework_TestCase { + + private $apiFactory; + private $application; + + protected function setUp() { + parent::setUp(); + + $this->apiFactory = new MwApiFactory(); + $this->application = Application::getInstance(); + } + + protected function tearDown() { + Application::clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $instance = new Info( + $this->apiFactory->newApiMain( array() ), + 'smwinfo' + ); + + $this->assertInstanceOf( + 'SMW\MediaWiki\Api\Info', + $instance + ); + } + + /** + * @dataProvider typeDataProvider + */ + public function testExecuteOnStore( $queryParameters, $expectedType ) { + + $result = $this->apiFactory->doApiRequest( array( + 'action' => 'smwinfo', + 'info' => $queryParameters + ) ); + + if ( $expectedType === 'integer' ) { + return $this->assertGreaterThanOrEqual( 0, $result['info'][$queryParameters] ); + } + + $this->assertInternalType( + 'array', + $result['info'][$queryParameters] + ); + } + + /** + * @dataProvider countDataProvider + */ + public function testExecuteOnMockStore( $statistics, $type, $expected ) { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $store->expects( $this->atLeastOnce() ) + ->method( 'getStatistics' ) + ->will( $this->returnValue( $statistics ) ); + + $this->application->registerObject( 'Store', $store ); + + $instance = new Info( + $this->apiFactory->newApiMain( array( 'info' => $type ) ), + 'smwinfo' + ); + + $instance->execute(); + + $result = $instance->getResultData(); + + $this->assertEquals( + $expected, + $result['info'][ $type ] + ); + } + + /** + * Test unknown query parameter + * + * Only valid parameters will yield an info array while an unknown parameter + * will produce a "warnings" array. + * + * @since 1.9 + */ + public function testUnknownQueryParameter() { + + $data = $this->apiFactory->doApiRequest( array( + 'action' => 'smwinfo', + 'info' => 'Foo' + ) ); + + $this->assertInternalType( + 'array', + $data['warnings'] + ); + } + + public function countDataProvider() { + return array( + array( array( 'QUERYFORMATS' => array( 'table' => 3 ) ), 'formatcount', array( 'table' => 3 ) ), + array( array( 'PROPUSES' => 34 ), 'propcount', 34 ), + array( array( 'USEDPROPS' => 51 ), 'usedpropcount', 51 ), + array( array( 'DECLPROPS' => 67 ), 'declaredpropcount', 67 ), + array( array( 'OWNPAGE' => 99 ), 'proppagecount', 99 ), + array( array( 'QUERY' => 11 ), 'querycount', 11 ), + array( array( 'QUERYSIZE' => 24 ), 'querysize', 24 ), + array( array( 'CONCEPTS' => 17 ), 'conceptcount', 17 ), + array( array( 'SUBOBJECTS' => 88 ), 'subobjectcount', 88 ), + ); + } + + public function typeDataProvider() { + return array( + array( 'proppagecount', 'integer' ), + array( 'propcount', 'integer' ), + array( 'querycount', 'integer' ), + array( 'usedpropcount', 'integer' ), + array( 'declaredpropcount', 'integer' ), + array( 'conceptcount', 'integer' ), + array( 'querysize', 'integer' ), + array( 'subobjectcount', 'integer' ), + array( 'formatcount', 'array' ) + ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/QueryTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/QueryTest.php new file mode 100644 index 00000000..0016ae97 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/QueryTest.php @@ -0,0 +1,133 @@ +<?php + +namespace SMW\Tests\MediaWiki\Api; + +use SMW\Tests\Util\MwApiFactory; + +use SMW\StoreFactory; +use SMW\Application; + +use ReflectionClass; + +/** + * @covers \SMW\MediaWiki\Api\Query + * + * @group SMW + * @group SMWExtension + * @group API + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class QueryTest extends \PHPUnit_Framework_TestCase { + + private $apiFactory; + private $application; + + protected function setUp() { + parent::setUp(); + + $this->apiFactory = new MwApiFactory(); + $this->application = Application::getInstance(); + } + + protected function tearDown() { + Application::clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $instance = $this->getMockBuilder( '\SMW\MediaWiki\Api\Query' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Api\Query', + $instance + ); + } + + public function testQueryAndQueryResult() { + + $instance = $this->getMockBuilder( '\SMW\MediaWiki\Api\Query' ) + ->disableOriginalConstructor() + ->getMock(); + + $reflector = new ReflectionClass( '\SMW\MediaWiki\Api\Query' ); + $getQuery = $reflector->getMethod( 'getQuery' ); + $getQuery->setAccessible( true ); + $query = $getQuery->invoke( $instance, '[[Modification date::+]]', array(), array() ); + + $this->assertInstanceOf( + '\SMWQuery', + $query + ); + + $getQueryResult = $reflector->getMethod( 'getQueryResult' ); + $getQueryResult->setAccessible( true ); + + $this->assertInstanceOf( + '\SMWQueryResult', + $getQueryResult->invoke( $instance, $query ) + ); + } + + public function testAddQueryResultOnMockStore() { + + // Minimalistic test case to verify executability + // For a full coverage, use Api\QueryResultFormatterTest + $test = array( + 'results' => array( + 'Foo' => array( + 'printouts' => array( 'lula' => array( 'lila' ) ) + ) + ), + 'printrequests' => array( 'Bar' ), + 'meta' => array( 'count' => 5, 'offset' => 5 ) + ); + + $queryResult = $this->getMockBuilder( '\SMWQueryResult' ) + ->disableOriginalConstructor() + ->getMock(); + + $queryResult->expects( $this->atLeastOnce() ) + ->method( 'toArray' ) + ->will( $this->returnValue( $test ) ); + + $queryResult->expects( $this->atLeastOnce() ) + ->method( 'getErrors' ) + ->will( $this->returnValue( array() ) ); + + $queryResult->expects( $this->atLeastOnce() ) + ->method( 'hasFurtherResults' ) + ->will( $this->returnValue( true ) ); + + $apiResult = $this->apiFactory->newApiResult( array() ); + + $reflector = new ReflectionClass( '\SMW\MediaWiki\Api\Query' ); + $method = $reflector->getMethod( 'addQueryResult' ); + $method->setAccessible( true ); + + $instance = $this->getMockBuilder( '\SMW\MediaWiki\Api\Query' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance->expects( $this->atLeastOnce() ) + ->method( 'getResult' ) + ->will( $this->returnValue( $apiResult ) ); + + $method->invoke( $instance, $queryResult ); + + $this->assertInternalType( 'array', $apiResult->getData() ); + + $this->assertEquals( + array( 'query' => $test, 'query-continue-offset' => 10 ), + $apiResult->getData() + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/DatabaseTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/DatabaseTest.php new file mode 100644 index 00000000..86a5c1f2 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/DatabaseTest.php @@ -0,0 +1,207 @@ +<?php + +namespace SMW\Tests\MediaWiki; + +use SMW\Tests\Util\Mock\MockDBConnectionProvider; +use SMW\MediaWiki\Database; + +/** + * @covers \SMW\MediaWiki\Database + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9.0.2 + * + * @author mwjames + */ +class DatabaseTest extends \PHPUnit_Framework_TestCase { + + public function getClass() { + return '\SMW\MediaWiki\Database'; + } + + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), new Database( new MockDBConnectionProvider ) ); + } + + public function testAquireConnection() { + + $instance = new Database( new MockDBConnectionProvider, new MockDBConnectionProvider ); + + $this->assertInstanceOf( 'DatabaseBase', $instance->acquireReadConnection() ); + $this->assertInstanceOf( 'DatabaseBase', $instance->acquireWriteConnection() ); + } + + public function testNumRowsMethod() { + + $connectionProvider = new MockDBConnectionProvider(); + $database = $connectionProvider->getMockDatabase(); + + $database->expects( $this->once() ) + ->method( 'numRows' ) + ->with( $this->equalTo( 'Fuyu' ) ) + ->will( $this->returnValue( 1 ) ); + + $instance = new Database( $connectionProvider ); + + $this->assertEquals( 1, $instance->numRows( 'Fuyu' ) ); + + } + + public function testAddQuotesMethod() { + + $connectionProvider = new MockDBConnectionProvider(); + $database = $connectionProvider->getMockDatabase(); + + $database->expects( $this->once() ) + ->method( 'addQuotes' ) + ->with( $this->equalTo( 'Fan' ) ) + ->will( $this->returnValue( 'Fan' ) ); + + $instance = new Database( $connectionProvider ); + + $this->assertEquals( 'Fan', $instance->addQuotes( 'Fan' ) ); + + } + + /** + * @dataProvider dbTypeProvider + */ + public function testTableNameMethod( $type ) { + + $connectionProvider = new MockDBConnectionProvider(); + $database = $connectionProvider->getMockDatabase(); + + $database->expects( $this->any() ) + ->method( 'tableName' ) + ->with( $this->equalTo( 'Foo' ) ) + ->will( $this->returnValue( 'Foo' ) ); + + $database->expects( $this->once() ) + ->method( 'getType' ) + ->will( $this->returnValue( $type ) ); + + $instance = new Database( $connectionProvider ); + + $this->assertEquals( 'Foo', $instance->tableName( 'Foo' ) ); + + } + + public function testSelectMethod() { + + $resultWrapper = $this->getMockBuilder( 'ResultWrapper' ) + ->disableOriginalConstructor() + ->getMock(); + + $connectionProvider = new MockDBConnectionProvider(); + $database = $connectionProvider->getMockDatabase(); + + $database->expects( $this->once() ) + ->method( 'select' ) + ->will( $this->returnValue( $resultWrapper ) ); + + $instance = new Database( $connectionProvider ); + + $this->assertInstanceOf( 'ResultWrapper', $instance->select( 'Foo', 'Bar', '', __METHOD__ ) ); + + } + + public function testSelectFieldMethod() { + + $connectionProvider = new MockDBConnectionProvider(); + $database = $connectionProvider->getMockDatabase(); + + $database->expects( $this->once() ) + ->method( 'selectField' ) + ->with( $this->equalTo( 'Foo' ) ) + ->will( $this->returnValue( 'Bar' ) ); + + $instance = new Database( $connectionProvider ); + + $this->assertEquals( 'Bar', $instance->selectField( 'Foo', 'Bar', '', __METHOD__, array() ) ); + } + + public function testQueryOnSQLite() { + + $resultWrapper = $this->getMockBuilder( 'ResultWrapper' ) + ->disableOriginalConstructor() + ->getMock(); + + $readConnection = new MockDBConnectionProvider(); + $read = $readConnection->getMockDatabase(); + + $read->expects( $this->any() ) + ->method( 'getType' ) + ->will( $this->returnValue( 'sqlite' ) ); + + $writeConnection = new MockDBConnectionProvider(); + $write = $writeConnection->getMockDatabase(); + + $write->expects( $this->once() ) + ->method( 'query' ) + ->with( $this->equalTo( 'TEMP' ) ) + ->will( $this->returnValue( $resultWrapper ) ); + + $instance = new Database( $readConnection, $writeConnection ); + + $this->assertInstanceOf( + 'ResultWrapper', + $instance->query( 'TEMPORARY' ) + ); + } + + public function testSelectThrowsException() { + + $instance = new Database( new MockDBConnectionProvider ); + + $this->setExpectedException( 'RuntimeException' ); + + $this->assertInstanceOf( + 'ResultWrapper', + $instance->select( 'Foo', 'Bar', '', __METHOD__ ) + ); + } + + public function testQueryThrowsException() { + + $connectionProvider = new MockDBConnectionProvider(); + $database = $connectionProvider->getMockDatabase(); + + $databaseException = new \DBError( $database, 'foo' ); + + $database->expects( $this->once() ) + ->method( 'query' ) + ->will( $this->throwException( $databaseException ) ); + + $instance = new Database( $connectionProvider ); + + $this->setExpectedException( 'RuntimeException' ); + + $this->assertInstanceOf( + 'ResultWrapper', + $instance->query( 'Foo', __METHOD__ ) + ); + } + + public function testMissingWriteConnectionThrowsException() { + + $this->setExpectedException( 'RuntimeException' ); + + $instance = new Database( new MockDBConnectionProvider ); + $this->assertInstanceOf( 'ResultWrapper', $instance->acquireWriteConnection() ); + + } + + public function dbTypeProvider() { + return array( + array( 'mysql' ), + array( 'sqlite' ), + array( 'postgres' ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/DirectDBConnectionProviderTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/DirectDBConnectionProviderTest.php new file mode 100644 index 00000000..59f3905b --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/DirectDBConnectionProviderTest.php @@ -0,0 +1,55 @@ +<?php + +namespace SMW\Tests\MediaWiki; + +use SMW\MediaWiki\DirectDBConnectionProvider; + +/** + * @covers \SMW\MediaWiki\DirectDBConnectionProvider + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9.1 + * + * @author mwjames + */ +class DirectDBConnectionProviderTest extends \PHPUnit_Framework_TestCase { + + public function getClass() { + return '\SMW\MediaWiki\DirectDBConnectionProvider'; + } + + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), new DirectDBConnectionProvider ); + } + + public function testSetGetConnection() { + + $database = $this->getMockBuilder( 'DatabaseMysql' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new DirectDBConnectionProvider; + $instance->setConnection( $database ); + + $this->assertInstanceOf( 'DatabaseBase', $instance->getConnection() ); + $this->assertTrue( $database === $instance->getConnection() ); + + $instance->releaseConnection(); + + } + + public function testGetConnectionThrowsException() { + + $this->setExpectedException( 'RuntimeException' ); + + $instance = new DirectDBConnectionProvider; + $this->assertInstanceOf( 'DatabaseBase', $instance->getConnection() ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/EditInfoProviderTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/EditInfoProviderTest.php new file mode 100644 index 00000000..6521dbd8 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/EditInfoProviderTest.php @@ -0,0 +1,223 @@ +<?php + +namespace SMW\Tests\MediaWiki; + +use SMW\MediaWiki\EditInfoProvider; +use SMW\Tests\Util\Mock\MockTitle; + +use ParserOutput; + +/** + * @covers \SMW\MediaWiki\EditInfoProvider + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class EditInfoProviderTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $revision = $this->getMockBuilder( '\Revision' ) + ->disableOriginalConstructor() + ->getMock(); + + $user = $this->getMockBuilder( '\User' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\EditInfoProvider', + new EditInfoProvider( $wikiPage, $revision, $user ) + ); + } + + /** + * @dataProvider wikiPageDataProvider + */ + public function testFetchContentInfo( $parameters, $expected ) { + + $instance = new EditInfoProvider( + $parameters['wikiPage'], + $parameters['revision'] + ); + + $this->assertEquals( + $expected, + $instance->fetchEditInfo()->getOutput() + ); + } + + /** + * @dataProvider wikiPageDataProvider + */ + public function testFetchContentInfoWithDisabledContentHandler( $parameters, $expected ) { + + $instance = $this->getMock( '\SMW\MediaWiki\EditInfoProvider', + array( 'hasContentForEditMethod' ), + array( + $parameters['wikiPage'], + $parameters['revision'], + null + ) + ); + + $instance->expects( $this->any() ) + ->method( 'hasContentForEditMethod' ) + ->will( $this->returnValue( false ) ); + + $this->assertEquals( + $expected, + $instance->fetchEditInfo()->getOutput() + ); + } + + public function wikiPageDataProvider() { + + $revision = $this->getMockBuilder( '\Revision' ) + ->disableOriginalConstructor() + ->getMock(); + + $revision->expects( $this->any() ) + ->method( 'getRawText' ) + ->will( $this->returnValue( 'Foo' ) ); + + $revision->expects( $this->any() ) + ->method( 'getContent' ) + ->will( $this->returnValue( $this->newContent() ) ); + + #0 No parserOutput object + $editInfo = (object)array(); + $editInfo->output = null; + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage->expects( $this->any() ) + ->method( 'prepareContentForEdit' ) + ->will( $this->returnValue( $editInfo ) ); + + $wikiPage->expects( $this->any() ) + ->method( 'prepareTextForEdit' ) + ->will( $this->returnValue( $editInfo ) ); + + $provider[] = array( + array( + 'editInfo' => $editInfo, + 'wikiPage' => $wikiPage, + 'revision' => $revision + ), + null + ); + + #1 + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage->expects( $this->any() ) + ->method( 'prepareContentForEdit' ) + ->will( $this->returnValue( false ) ); + + $wikiPage->expects( $this->any() ) + ->method( 'prepareTextForEdit' ) + ->will( $this->returnValue( false ) ); + + $provider[] = array( + array( + 'editInfo' => false, + 'wikiPage' => $wikiPage, + 'revision' => $revision + ), + null + ); + + #2 + $editInfo = (object)array(); + $editInfo->output = new ParserOutput(); + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage->expects( $this->any() ) + ->method( 'prepareContentForEdit' ) + ->will( $this->returnValue( $editInfo ) ); + + $wikiPage->expects( $this->any() ) + ->method( 'prepareTextForEdit' ) + ->will( $this->returnValue( $editInfo ) ); + + $provider[] = array( + array( + 'editInfo' => $editInfo, + 'wikiPage' => $wikiPage, + 'revision' => $revision + ), + $editInfo->output + ); + + #3 + $editInfo = (object)array(); + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage->expects( $this->any() ) + ->method( 'prepareContentForEdit' ) + ->will( $this->returnValue( $editInfo ) ); + + $wikiPage->expects( $this->any() ) + ->method( 'prepareTextForEdit' ) + ->will( $this->returnValue( $editInfo ) ); + + $provider[] = array( + array( + 'editInfo' => $editInfo, + 'wikiPage' => $wikiPage, + 'revision' => $revision + ), + null + ); + + return $provider; + } + + private function newContent() { + + if ( !class_exists( 'ContentHandler' ) ) { + return null; + } + + $contentHandler = $this->getMockBuilder( '\ContentHandler' ) + ->disableOriginalConstructor() + ->getMock(); + + $contentHandler->expects( $this->atLeastOnce() ) + ->method( 'getDefaultFormat' ) + ->will( $this->returnValue( 'Foo' ) ); + + $content = $this->getMockBuilder( '\Content' ) + ->disableOriginalConstructor() + ->getMock(); + + $content->expects( $this->atLeastOnce() ) + ->method( 'getContentHandler' ) + ->will( $this->returnValue( $contentHandler ) ); + + return $content; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ArticleDeleteTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ArticleDeleteTest.php new file mode 100644 index 00000000..bb3b4afe --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ArticleDeleteTest.php @@ -0,0 +1,107 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\Tests\Util\Mock\MockTitle; +use SMW\Tests\Util\Mock\MockSuperUser; + +use SMW\MediaWiki\Hooks\ArticleDelete; +use SMW\Application; +use SMW\Settings; + +use Title; + +/** + * @covers \SMW\MediaWiki\Hooks\ArticleDelete + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class ArticleDeleteTest extends \PHPUnit_Framework_TestCase { + + private $application; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + $this->application->getSettings()->set( 'smwgEnableUpdateJobs', false ); + $this->application->getSettings()->set( 'smwgDeleteSubjectWithAssociatesRefresh', false ); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $user = $this->getMockBuilder( '\User' ) + ->disableOriginalConstructor() + ->getMock(); + + $reason = ''; + $error = ''; + + $instance = new ArticleDelete( + $wikiPage, + $user, + $reason, + $error + ); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\ArticleDelete', + $instance + ); + } + + public function testProcess() { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $store->expects( $this->atLeastOnce() ) + ->method( 'deleteSubject' ); + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( Title::newFromText( __METHOD__ ) ) ); + + $user = $this->getMockBuilder( '\User' ) + ->disableOriginalConstructor() + ->getMock(); + + $reason = ''; + $error = ''; + + $this->application->registerObject( 'Store', $store ); + + $instance = new ArticleDelete( + $wikiPage, + $user, + $reason, + $error + ); + + $this->assertTrue( $instance->process() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ArticleFromTitleTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ArticleFromTitleTest.php new file mode 100644 index 00000000..ea362ef2 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ArticleFromTitleTest.php @@ -0,0 +1,74 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\MediaWiki\Hooks\ArticleFromTitle; + +/** + * @covers \SMW\MediaWiki\Hooks\ArticleFromTitle + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class ArticleFromTitleTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $title = $this->getMockBuilder( '\Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\ArticleFromTitle', + new ArticleFromTitle( $title, $wikiPage ) + ); + } + + /** + * @dataProvider titleProvider + */ + public function testProcess( $namespace, $expected ) { + + $title = $this->getMockBuilder( '\Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( $namespace ) ); + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new ArticleFromTitle( $title, $wikiPage ); + $instance->process(); + + $this->assertInstanceOf( + $expected, + $wikiPage + ); + } + + public function titleProvider() { + + $provider = array( + array( SMW_NS_PROPERTY, 'SMWPropertyPage' ), + array( SMW_NS_CONCEPT, 'SMW\ConceptPage' ), + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ArticlePurgeTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ArticlePurgeTest.php new file mode 100644 index 00000000..b50bfc4d --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ArticlePurgeTest.php @@ -0,0 +1,185 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\Tests\Util\Mock\MockTitle; + +use SMW\MediaWiki\Hooks\ArticlePurge; +use SMW\Settings; +use SMW\FactboxCache; +use SMW\Application; + +use WikiPage; + +/** + * @covers \SMW\MediaWiki\Hooks\ArticlePurge + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class ArticlePurgeTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + 'SMW\MediaWiki\Hooks\ArticlePurge', + new ArticlePurge( $wikiPage ) + ); + } + + /** + * @dataProvider titleDataProvider + */ + public function testProcess( $setup, $expected ) { + + $wikiPage = new WikiPage( $setup['title'] ); + $pageId = $wikiPage->getTitle()->getArticleID(); + + Application::getInstance()->registerObject( 'Settings', Settings::newFromArray( array( + 'smwgCacheType' => 'hash', + 'smwgAutoRefreshOnPurge' => $setup['smwgAutoRefreshOnPurge'], + 'smwgFactboxCacheRefreshOnPurge' => $setup['smwgFactboxCacheRefreshOnPurge'] + ) ) ); + + $instance = new ArticlePurge( $wikiPage ); + $cache = Application::getInstance()->getCache(); + + $id = FactboxCache::newCacheId( $pageId ); + // $cache->setKey( $id )->set( true ); + + $this->assertEquals( + $expected['autorefreshPreProcess'], + $cache->setKey( $instance->newCacheId( $pageId ) )->get(), + 'Asserts the autorefresh cache status before processing' + ); + + // Travis 210.5, 305.3 + $travis = $cache->setKey( $id )->get(); + $travisText = json_encode( $travis ); + $this->assertEquals( + $expected['factboxPreProcess'], + $travis, + "Asserts the factbox cache status before processing, {$travisText}" + ); + + $this->assertFalse( + $cache->setKey( $instance->newCacheId( $pageId ) )->get(), + 'Asserts that before processing ...' + ); + + $result = $instance->process(); + + // Post-process check + $this->assertTrue( + $result, + 'Asserts that process() always returns true' + ); + + $this->assertEquals( + $expected['autorefreshPostProcess'], + $cache->setKey( $instance->newCacheId( $pageId ) )->get(), + 'Asserts the autorefresh cache status after processing' + ); + + $this->assertEquals( + $expected['factboxPostProcess'], + $cache->setCacheEnabled( true )->setKey( $id )->get(), + 'Asserts the factbox cache status after processing' + ); + } + + public function titleDataProvider() { + + $validIdTitle = MockTitle::buildMock( 'validIdTitle' ); + + $validIdTitle->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 9999 ) ); + + #0 Id = cache + $provider[] = array( + array( + 'title' => $validIdTitle, + 'smwgAutoRefreshOnPurge' => true, + 'smwgFactboxCacheRefreshOnPurge' => true + ), + array( + 'factboxPreProcess' => false, + 'autorefreshPreProcess' => false, + 'autorefreshPostProcess' => true, + 'factboxPostProcess' => false, + ) + ); + + #1 Disabled setting + $validIdTitle = MockTitle::buildMock( 'Disabled' ); + + $validIdTitle->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 9099 ) ); + + $provider[] = array( + array( + 'title' => $validIdTitle, + 'smwgAutoRefreshOnPurge' => false, + 'smwgFactboxCacheRefreshOnPurge' => false + ), + array( + 'factboxPreProcess' => false, + 'autorefreshPreProcess' => false, + 'autorefreshPostProcess' => false, + 'factboxPostProcess' => false, + ) + ); + + // #2 No Id + $nullIdTitle = MockTitle::buildMock( 'NullId' ); + + $nullIdTitle->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 0 ) ); + + $provider[] = array( + array( + 'title' => $nullIdTitle, + 'smwgAutoRefreshOnPurge' => true, + 'smwgFactboxCacheRefreshOnPurge' => true + ), + array( + 'factboxPreProcess' => false, + 'autorefreshPreProcess' => false, + 'autorefreshPostProcess' => false, + 'factboxPostProcess' => false, + ) + ); + + #3 No Id + $provider[] = array( + array( + 'title' => $nullIdTitle, + 'smwgAutoRefreshOnPurge' => true, + 'smwgFactboxCacheRefreshOnPurge' => false + ), + array( + 'factboxPreProcess' => false, + 'autorefreshPreProcess' => false, + 'autorefreshPostProcess' => false, + 'factboxPostProcess' => false, + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/BaseTemplateToolboxTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/BaseTemplateToolboxTest.php new file mode 100644 index 00000000..e8c0a22e --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/BaseTemplateToolboxTest.php @@ -0,0 +1,199 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\Tests\Util\Mock\MockTitle; + +use SMW\MediaWiki\Hooks\BaseTemplateToolbox; +use SMW\Application; +use SMW\Settings; + +use Title; + +/** + * @covers \SMW\MediaWiki\Hooks\BaseTemplateToolbox + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class BaseTemplateToolboxTest extends \PHPUnit_Framework_TestCase { + + protected function tearDown() { + Application::clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $skinTemplate = $this->getMockBuilder( '\SkinTemplate' ) + ->disableOriginalConstructor() + ->getMock(); + + $toolbox = ''; + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\BaseTemplateToolbox', + new BaseTemplateToolbox( $skinTemplate, $toolbox ) + ); + } + + /** + * @dataProvider skinTemplateDataProvider + */ + public function testProcess( $setup, $expected ) { + + $toolbox = ''; + + Application::getInstance()->registerObject( + 'Settings', + Settings::newFromArray( $setup['settings'] ) + ); + + $instance = new BaseTemplateToolbox( $setup['skinTemplate'], $toolbox ); + + $this->assertTrue( $instance->process() ); + + if ( $expected['count'] == 0 ) { + return $this->assertEmpty( $toolbox ); + } + + $this->assertCount( + $expected['count'], + $toolbox['smw-browse'] + ); + } + + public function skinTemplateDataProvider() { + + #0 Standard title + $settings = array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgToolboxBrowseLink' => true + ); + + $message = $this->getMockBuilder( '\Message' ) + ->disableOriginalConstructor() + ->getMock(); + + $skin = $this->getMockBuilder( '\Skin' ) + ->disableOriginalConstructor() + ->getMock(); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( Title::newFromText( __METHOD__ ) ) ); + + $skin->expects( $this->any() ) + ->method( 'msg' ) + ->will( $this->returnValue( $message ) ); + + $skinTemplate = $this->getMockBuilder( '\SkinTemplate' ) + ->disableOriginalConstructor() + ->getMock(); + + $skinTemplate->expects( $this->atLeastOnce() ) + ->method( 'getSkin' ) + ->will( $this->returnValue( $skin ) ); + + $skinTemplate->data['isarticle'] = true; + + $provider[] = array( + array( 'skinTemplate' => $skinTemplate, 'settings' => $settings ), + array( 'count' => 4 ), + ); + + #1 isarticle = false + $skinTemplate = $this->getMockBuilder( '\SkinTemplate' ) + ->disableOriginalConstructor() + ->getMock(); + + $skinTemplate->expects( $this->atLeastOnce() ) + ->method( 'getSkin' ) + ->will( $this->returnValue( $skin ) ); + + $skinTemplate->data['isarticle'] = false; + + $provider[] = array( + array( 'skinTemplate' => $skinTemplate, 'settings' => $settings ), + array( 'count' => 0 ), + ); + + #2 smwgToolboxBrowseLink = false + $skinTemplate = $this->getMockBuilder( '\SkinTemplate' ) + ->disableOriginalConstructor() + ->getMock(); + + $skinTemplate->expects( $this->atLeastOnce() ) + ->method( 'getSkin' ) + ->will( $this->returnValue( $skin ) ); + + $skinTemplate->data['isarticle'] = true; + + $settings = array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgToolboxBrowseLink' => false + ); + + $provider[] = array( + array( 'skinTemplate' => $skinTemplate, 'settings' => $settings ), + array( 'count' => 0 ), + ); + + #3 smwgNamespacesWithSemanticLinks = false + $settings = array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => false ), + 'smwgToolboxBrowseLink' => true + ); + + $provider[] = array( + array( 'skinTemplate' => $skinTemplate, 'settings' => $settings ), + array( 'count' => 0 ), + ); + + #4 Special page + $settings = array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgToolboxBrowseLink' => true + ); + + $title = MockTitle::buildMock( __METHOD__ ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isSpecialPage' ) + ->will( $this->returnValue( true ) ); + + $skin = $this->getMockBuilder( '\Skin' ) + ->disableOriginalConstructor() + ->getMock(); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $skinTemplate = $this->getMockBuilder( '\SkinTemplate' ) + ->disableOriginalConstructor() + ->getMock(); + + $skinTemplate->expects( $this->atLeastOnce() ) + ->method( 'getSkin' ) + ->will( $this->returnValue( $skin ) ); + + $skinTemplate->data['isarticle'] = true; + + $provider[] = array( + array( 'skinTemplate' => $skinTemplate, 'settings' => $settings ), + array( 'count' => 0 ), + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/BeforeDisplayNoArticleTextTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/BeforeDisplayNoArticleTextTest.php new file mode 100644 index 00000000..671c7960 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/BeforeDisplayNoArticleTextTest.php @@ -0,0 +1,75 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\MediaWiki\Hooks\BeforeDisplayNoArticleText; + +/** + * @covers \SMW\MediaWiki\Hooks\BeforeDisplayNoArticleText + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class BeforeDisplayNoArticleTextTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\BeforeDisplayNoArticleText', + new BeforeDisplayNoArticleText( $wikiPage ) + ); + } + + /** + * @dataProvider titleProvider + */ + public function testPerformUpdate( $namespace, $text, $expected ) { + + $title = $this->getMockBuilder( '\Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $title->expects( $this->any() ) + ->method( 'getText' ) + ->will( $this->returnValue( $text ) ); + + $title->expects( $this->any() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( $namespace ) ); + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage->expects( $this->any() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $instance = new BeforeDisplayNoArticleText( $wikiPage ); + + $this->assertEquals( $expected, $instance->process() ); + } + + public function titleProvider() { + + $provider = array( + array( SMW_NS_PROPERTY, 'Modification date', false ), + array( SMW_NS_PROPERTY, 'Foo', true ), + array( NS_MAIN, 'Modification date', true ), + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/BeforePageDisplayTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/BeforePageDisplayTest.php new file mode 100644 index 00000000..75acd18c --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/BeforePageDisplayTest.php @@ -0,0 +1,134 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\Tests\Util\Mock\MockTitle; + +use SMW\MediaWiki\Hooks\BeforePageDisplay; + +use OutputPage; +use Language; + +/** + * @covers \SMW\MediaWiki\Hooks\BeforePageDisplay + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class BeforePageDisplayTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $skin = $this->getMockBuilder( '\Skin' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\BeforePageDisplay', + new BeforePageDisplay( $outputPage, $skin ) + ); + } + + /** + * @dataProvider titleDataProvider + */ + public function testProcess( $setup, $expected ) { + + $skin = $this->getMockBuilder( '\Skin' ) + ->disableOriginalConstructor() + ->getMock(); + + $context = new \RequestContext(); + $context->setTitle( $setup['title'] ); + $context->setLanguage( Language::factory( 'en' ) ); + + $outputPage = new OutputPage( $context ); + + $instance = new BeforePageDisplay( $outputPage, $skin ); + $result = $instance->process(); + + $this->assertInternalType( 'boolean', $result ); + $this->assertTrue( $result ); + + $contains = false; + + if ( method_exists( $outputPage, 'getHeadLinksArray' ) ) { + foreach ( $outputPage->getHeadLinksArray() as $key => $value ) { + if ( strpos( $value, 'ExportRDF' ) ){ + $contains = true; + break; + }; + } + } else{ + // MW 1.19 + if ( strpos( $outputPage->getHeadLinks(), 'ExportRDF' ) ){ + $contains = true; + }; + } + + $expected['result'] ? $this->assertTrue( $contains ) : $this->assertFalse( $contains ); + } + + public function titleDataProvider() { + + $language = Language::factory( 'en' ); + + #0 Standard title + $title = MockTitle::buildMockForMainNamespace(); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getPrefixedText' ) + ->will( $this->returnValue( 'Foo' ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isSpecialPage' ) + ->will( $this->returnValue( false ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getPageLanguage' ) + ->will( $this->returnValue( $language ) ); + + $provider[] = array( + array( + 'title' => $title + ), + array( + 'result' => true + ) + ); + + #1 as SpecialPage + $title = MockTitle::buildMock(); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isSpecialPage' ) + ->will( $this->returnValue( true ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getPageLanguage' ) + ->will( $this->returnValue( $language ) ); + + $provider[] = array( + array( + 'title' => $title + ), + array( + 'result' => false + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ExtensionSchemaUpdatesTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ExtensionSchemaUpdatesTest.php new file mode 100644 index 00000000..cdad04e9 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ExtensionSchemaUpdatesTest.php @@ -0,0 +1,48 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\MediaWiki\Hooks\ExtensionSchemaUpdates; + +/** + * @covers \SMW\MediaWiki\Hooks\ExtensionSchemaUpdates + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class ExtensionSchemaUpdatesTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $databaseUpdater = $this->getMockBuilder( '\DatabaseUpdater' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\ExtensionSchemaUpdates', + new ExtensionSchemaUpdates( $databaseUpdater ) + ); + } + + public function testProcess() { + + $databaseUpdater = $this->getMockBuilder( '\DatabaseUpdater' ) + ->disableOriginalConstructor() + ->setMethods( array( 'addExtensionUpdate' ) ) + ->getMockForAbstractClass(); + + $databaseUpdater->expects( $this->once() ) + ->method( 'addExtensionUpdate' ); + + $instance = new ExtensionSchemaUpdates( $databaseUpdater ); + $instance->process(); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ExtensionTypesTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ExtensionTypesTest.php new file mode 100644 index 00000000..b9318060 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ExtensionTypesTest.php @@ -0,0 +1,42 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\MediaWiki\Hooks\ExtensionTypes; + +/** + * @covers \SMW\MediaWiki\Hooks\ExtensionTypes + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class ExtensionTypesTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $extensionTypes = array(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\ExtensionTypes', + new ExtensionTypes( $extensionTypes ) + ); + } + + public function testProcess() { + + $extensionTypes = array(); + + $instance = new ExtensionTypes( $extensionTypes ); + $instance->process(); + + $this->assertArrayHasKey( 'semantic', $extensionTypes ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/FileUploadTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/FileUploadTest.php new file mode 100644 index 00000000..05c53ab9 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/FileUploadTest.php @@ -0,0 +1,91 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\MediaWiki\Hooks\FileUpload; +use SMW\Application; +use SMW\Settings; + +use ParserOutput; +use Title; + +/** + * @covers \SMW\MediaWiki\Hooks\FileUpload + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class FileUploadTest extends \PHPUnit_Framework_TestCase { + + private $application; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + + $settings = Settings::newFromArray( array( + 'smwgPageSpecialProperties' => array( '_MEDIA', '_MIME' ), + 'smwgCacheType' => 'hash', + 'smwgEnableUpdateJobs' => false + ) ); + + $this->application->registerObject( 'Settings', $settings ); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $file = $this->getMockBuilder( 'File' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\FileUpload', + new FileUpload( $file ) + ); + } + + public function testPerformUpdate() { + + $store = $this->getMockBuilder( 'SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->application->registerObject( 'Store', $store ); + + $file = $this->getMockBuilder( 'File' ) + ->disableOriginalConstructor() + ->getMock(); + + $file->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( Title::newFromText( __METHOD__ ) ) ); + + $contentParser = $this->getMockBuilder( '\SMW\ContentParser' ) + ->disableOriginalConstructor() + ->getMock(); + + $contentParser->expects( $this->atLeastOnce() ) + ->method( 'getOutput' ) + ->will( $this->returnValue( new ParserOutput() ) ); + + $this->application->registerObject( 'ContentParser', $contentParser ); + + $instance = new FileUpload( $file, false ); + $this->assertTrue( $instance->process() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/GetPreferencesTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/GetPreferencesTest.php new file mode 100644 index 00000000..e2daf5e7 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/GetPreferencesTest.php @@ -0,0 +1,52 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\MediaWiki\Hooks\GetPreferences; + +/** + * @covers \SMW\MediaWiki\Hooks\GetPreferences + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class GetPreferencesTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $user = $this->getMockBuilder( '\User' ) + ->disableOriginalConstructor() + ->getMock(); + + $preferences = array(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\GetPreferences', + new GetPreferences( $user, $preferences ) + ); + } + + public function testProcess() { + + $user = $this->getMockBuilder( '\User' ) + ->disableOriginalConstructor() + ->getMock(); + + $preferences = array(); + + $instance = new GetPreferences( $user, $preferences ); + $instance->process(); + + $this->assertArrayHasKey( 'smw-prefs-intro', $preferences ); + $this->assertArrayHasKey( 'smw-prefs-ask-options-tooltip-display', $preferences ); + $this->assertArrayHasKey( 'smw-prefs-ask-options-collapsed-default', $preferences ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/InternalParseBeforeLinksTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/InternalParseBeforeLinksTest.php new file mode 100644 index 00000000..4706efcb --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/InternalParseBeforeLinksTest.php @@ -0,0 +1,254 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\Tests\Util\SemanticDataValidator; +use SMW\Tests\Util\ParserFactory; +use SMW\Tests\Util\Mock\MockTitle; + +use SMW\MediaWiki\Hooks\InternalParseBeforeLinks; + +use SMW\Application; +use SMW\Settings; + +use Title; + +/** + * @covers \SMW\MediaWiki\Hooks\InternalParseBeforeLinks + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class InternalParseBeforeLinksTest extends \PHPUnit_Framework_TestCase { + + private $semanticDataValidator; + private $application; + + protected function setUp() { + parent::setUp(); + + $this->semanticDataValidator = new SemanticDataValidator(); + $this->application = Application::getInstance(); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $parser = $this->getMockBuilder( 'Parser' ) + ->disableOriginalConstructor() + ->getMock(); + + $text = ''; + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\InternalParseBeforeLinks', + new InternalParseBeforeLinks( $parser, $text ) + ); + } + + /** + * @dataProvider titleProvider + */ + public function testProcess( $title ) { + + $text = ''; + $parser = ParserFactory::newFromTitle( $title ); + + $instance = new InternalParseBeforeLinks( + $parser, + $text + ); + + $this->assertTrue( $instance->process() ); + } + + /** + * @dataProvider textDataProvider + */ + public function testSemanticDataParserOuputUpdateIntegration( $parameters, $expected ) { + + $text = $parameters['text']; + $parser = ParserFactory::newFromTitle( $parameters['title'] ); + + $instance = new InternalParseBeforeLinks( + $parser, + $text + ); + + $this->application->registerObject( + 'Settings', + Settings::newFromArray( $parameters['settings'] ) + ); + + $this->assertTrue( $instance->process() ); + $this->assertEquals( $expected['resultText'], $text ); + + $parserData = $this->application->newParserData( + $parser->getTitle(), + $parser->getOutput() + ); + + $this->assertEquals( + $expected['propertyCount'] > 0, + $parser->getOutput()->getProperty( 'smw-semanticdata-status' ) + ); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $parserData->getSemanticData() + ); + } + + public function titleProvider() { + + #2 + $provider[] = array( Title::newFromText( __METHOD__ ) ); + + $title = MockTitle::buildMockForMainNamespace(); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isSpecialPage' ) + ->will( $this->returnValue( true ) ); + + #1 + $provider[] = array( $title ); + + $title = MockTitle::buildMockForMainNamespace(); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isSpecialPage' ) + ->will( $this->returnValue( true ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isSpecial' ) + ->will( $this->returnValue( true ) ); + + #2 + $provider[] = array( $title ); + + $title = MockTitle::buildMockForMainNamespace(); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isSpecialPage' ) + ->will( $this->returnValue( true ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isSpecial' ) + ->will( $this->returnValue( false ) ); + + #3 + $provider[] = array( $title ); + + return $provider; + } + + public function textDataProvider() { + + $provider = array(); + + // #0 NS_MAIN; [[FooBar...]] with a different caption + $title = Title::newFromText( __METHOD__, NS_MAIN ); + + $provider[] = array( + array( + 'title' => $title, + 'settings' => array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + ), + 'text' => 'Lorem ipsum dolor sit &$% [[FooBar::dictumst|寒い]]' . + ' [[Bar::tincidunt semper]] facilisi {{volutpat}} Ut quis' . + ' [[foo::9001]] et Donec.', + ), + array( + 'resultText' => 'Lorem ipsum dolor sit &$% [[:Dictumst|寒い]]' . + ' [[:Tincidunt semper|tincidunt semper]] facilisi {{volutpat}} Ut quis' . + ' [[:9001|9001]] et Donec.', + 'propertyCount' => 3, + 'propertyLabels' => array( 'Foo', 'Bar', 'FooBar' ), + 'propertyValues' => array( 'Dictumst', 'Tincidunt semper', '9001' ) + ) + ); + + $provider[] = array( + array( + 'title' => $title, + 'settings' => array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + ), + 'text' => '#REDIRECT [[Foo]]', + ), + array( + 'resultText' => '#REDIRECT [[Foo]]', + 'propertyCount' => 1, + 'propertyValues' => array( 'Foo' ) + ) + ); + + // #1 NS_SPECIAL, processed but no annotations + $title = Title::newFromText( 'Ask', NS_SPECIAL ); + + $provider[] = array( + array( + 'title' => $title, + 'settings' => array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + 'smwgEnabledSpecialPage' => array( 'Ask', 'Foo' ) + ), + 'text' => 'Lorem ipsum dolor sit &$% [[FooBar::dictumst|寒い]]' . + ' [[Bar::tincidunt semper]] facilisi {{volutpat}} Ut quis' . + ' [[foo::9001]] et Donec.', + ), + array( + 'resultText' => 'Lorem ipsum dolor sit &$% [[:Dictumst|寒い]]' . + ' [[:Tincidunt semper|tincidunt semper]] facilisi {{volutpat}} Ut quis' . + ' [[:9001|9001]] et Donec.', + 'propertyCount' => 0 + ) + ); + + // #2 NS_SPECIAL, not processed + $title = Title::newFromText( 'Foo', NS_SPECIAL ); + + $provider[] = array( + array( + 'title' => $title, + 'settings' => array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + 'smwgEnabledSpecialPage' => array( 'Ask', 'Foo' ) + ), + 'text' => 'Lorem ipsum dolor sit &$% [[FooBar::dictumst|寒い]]' . + ' [[Bar::tincidunt semper]] facilisi {{volutpat}} Ut quis' . + ' [[foo::9001]] et Donec.', + ), + array( + 'resultText' => 'Lorem ipsum dolor sit &$% [[FooBar::dictumst|寒い]]' . + ' [[Bar::tincidunt semper]] facilisi {{volutpat}} Ut quis' . + ' [[foo::9001]] et Donec.', + 'propertyCount' => 0 + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/LinksUpdateConstructedTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/LinksUpdateConstructedTest.php new file mode 100644 index 00000000..46d68d65 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/LinksUpdateConstructedTest.php @@ -0,0 +1,82 @@ +<?php + +namespace SMW\Test\MediaWiki\Hooks; + +use SMW\MediaWiki\Hooks\LinksUpdateConstructed; +use SMW\Application; + +use ParserOutput; +use LinksUpdate; +use Title; + +/** + * @covers \SMW\MediaWiki\Hooks\LinksUpdateConstructed + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class LinksUpdateConstructedTest extends \PHPUnit_Framework_TestCase { + + private $application; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->application->registerObject( 'Store', $store ); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $linksUpdate = $this->getMockBuilder( '\LinksUpdate' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\LinksUpdateConstructed', + new LinksUpdateConstructed( $linksUpdate ) + ); + } + + public function testProcess() { + + $title = Title::newFromText( __METHOD__ ); + $title->resetArticleID( rand( 1, 1000 ) ); + + $parserOutput = new ParserOutput(); + $parserOutput->setTitleText( $title->getPrefixedText() ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( 'updateData' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->atLeastOnce() ) + ->method( 'updateData' ); + + $this->application->registerObject( 'Store', $store ); + + $instance = new LinksUpdateConstructed( new LinksUpdate( $title, $parserOutput ) ); + + $this->assertTrue( $instance->process() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/NewRevisionFromEditCompleteTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/NewRevisionFromEditCompleteTest.php new file mode 100644 index 00000000..45631eff --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/NewRevisionFromEditCompleteTest.php @@ -0,0 +1,210 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\Tests\Util\SemanticDataValidator; + +use SMW\MediaWiki\Hooks\NewRevisionFromEditComplete; +use SMW\DIProperty; +use SMW\Application; +use SMW\Settings; + +use ParserOutput; +use WikiPage; +use Revision; +use Title; + +/** + * @covers \SMW\MediaWiki\Hooks\NewRevisionFromEditComplete + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class NewRevisionFromEditCompleteTest extends \PHPUnit_Framework_TestCase { + + private $application; + private $semanticDataValidator; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + $this->semanticDataValidator = new SemanticDataValidator(); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $revision = $this->getMockBuilder( '\Revision' ) + ->disableOriginalConstructor() + ->getMock(); + + $user = $this->getMockBuilder( '\User' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\NewRevisionFromEditComplete', + new NewRevisionFromEditComplete( $wikiPage, $revision, 0, $user ) + ); + } + + /** + * @dataProvider wikiPageDataProvider + */ + public function testProcess( $parameters, $expected ) { + + $this->application->registerObject( + 'Settings', + Settings::newFromArray( $parameters['settings'] ) + ); + + $instance = new NewRevisionFromEditComplete( + $parameters['wikiPage'], + $parameters['revision'], + 0 + ); + + $this->assertTrue( $instance->process() ); + + $editInfo = $parameters['editInfo']; + + if ( $editInfo && $editInfo->output instanceof ParserOutput ) { + + $parserData = $this->application->newParserData( + $parameters['wikiPage']->getTitle(), + $editInfo->output + ); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $parserData->getSemanticData() + ); + } + } + + public function wikiPageDataProvider() { + + $revision = $this->getMockBuilder( '\Revision' ) + ->disableOriginalConstructor() + ->getMock(); + + $revision->expects( $this->any() ) + ->method( 'getRawText' ) + ->will( $this->returnValue( 'Foo' ) ); + + $revision->expects( $this->any() ) + ->method( 'getContent' ) + ->will( $this->returnValue( $this->newContent() ) ); + + #0 No parserOutput object + $editInfo = (object)array(); + $editInfo->output = null; + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage->expects( $this->any() ) + ->method( 'prepareContentForEdit' ) + ->will( $this->returnValue( $editInfo ) ); + + $wikiPage->expects( $this->any() ) + ->method( 'prepareTextForEdit' ) + ->will( $this->returnValue( $editInfo ) ); + + $provider[] = array( + array( + 'editInfo' => $editInfo, + 'wikiPage' => $wikiPage, + 'revision' => $revision, + 'settings' => array() + ), + array() + ); + + #1 With annotation + $editInfo = (object)array(); + $editInfo->output = new ParserOutput(); + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage->expects( $this->any() ) + ->method( 'prepareContentForEdit' ) + ->will( $this->returnValue( $editInfo ) ); + + $wikiPage->expects( $this->any() ) + ->method( 'prepareTextForEdit' ) + ->will( $this->returnValue( $editInfo ) ); + + $wikiPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( Title::newFromText( __METHOD__ ) ) ); + + $wikiPage->expects( $this->atLeastOnce() ) + ->method( 'getTimestamp' ) + ->will( $this->returnValue( 1272508903 ) ); + + $provider[] = array( + array( + 'editInfo' => $editInfo, + 'wikiPage' => $wikiPage, + 'revision' => $revision, + 'settings' => array( + 'smwgPageSpecialProperties' => array( DIProperty::TYPE_MODIFICATION_DATE ) + ) + ), + array( + 'propertyCount' => 1, + 'propertyKeys' => '_MDAT', + 'propertyValues' => array( '2010-04-29T02:41:43' ), + ) + ); + + return $provider; + } + + private function newContent() { + + if ( !class_exists( 'ContentHandler' ) ) { + return null; + } + + $contentHandler = $this->getMockBuilder( '\ContentHandler' ) + ->disableOriginalConstructor() + ->getMock(); + + $contentHandler->expects( $this->atLeastOnce() ) + ->method( 'getDefaultFormat' ) + ->will( $this->returnValue( 'Foo' ) ); + + $content = $this->getMockBuilder( '\Content' ) + ->disableOriginalConstructor() + ->getMock(); + + $content->expects( $this->atLeastOnce() ) + ->method( 'getContentHandler' ) + ->will( $this->returnValue( $contentHandler ) ); + + return $content; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/OutputPageParserOutputTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/OutputPageParserOutputTest.php new file mode 100644 index 00000000..bafdde8c --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/OutputPageParserOutputTest.php @@ -0,0 +1,347 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\Tests\Util\Mock\MockTitle; + +use SMW\MediaWiki\Hooks\OutputPageParserOutput; + +use SMW\Settings; +use SMW\Application; +use SMW\DIWikiPage; +use SMW\DIProperty; + +use ParserOutput; +use Language; + +/** + * @covers \SMW\MediaWiki\Hooks\OutputPageParserOutput + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group medium + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class OutputPageParserOutputTest extends \PHPUnit_Framework_TestCase { + + private $application; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + + $settings = Settings::newFromArray( array( + 'smwgShowFactbox' => SMW_FACTBOX_NONEMPTY, + 'smwgFactboxUseCache' => true, + 'smwgCacheType' => 'hash', + 'smwgLinksInValues' => false, + 'smwgInlineErrors' => true, + ) ); + + $this->application->registerObject( 'Settings', $settings ); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $parserOutput = $this->getMockBuilder( '\ParserOutput' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\OutputPageParserOutput', + new OutputPageParserOutput( $outputPage, $parserOutput ) + ); + } + + /** + * @dataProvider outputDataProvider + */ + public function testProcess( $parameters, $expected ) { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->application->registerObject( 'Store', $store ); + + $this->application->getSettings()->set( + 'smwgNamespacesWithSemanticLinks', + $parameters['smwgNamespacesWithSemanticLinks'] + ); + + $outputPage = $parameters['outputPage']; + $parserOutput = $parameters['parserOutput']; + + $instance = new OutputPageParserOutput( $outputPage, $parserOutput ); + + $factboxCache = $this->application->newFactboxBuilder()->newFactboxCache( $outputPage ); + $this->assertEmpty( $factboxCache->retrieveContent() ); + + $instance->process(); + + if ( $expected['text'] == '' ) { + return $this->assertFalse( isset( $outputPage->mSMWFactboxText ) ); + } + + // For expected content continue to verify that the outputPage was amended and + // that the content is also available via the CacheStore + $text = $outputPage->mSMWFactboxText; + + $this->assertContains( $expected['text'], $text ); + + $this->assertEquals( + $text, + $factboxCache->retrieveContent(), + 'Asserts that retrieveContent() returns an expected text' + ); + + // Deliberately clear the outputPage Property to retrieve + // content from the CacheStore + unset( $outputPage->mSMWFactboxText ); + + $this->assertEquals( + $text, + $factboxCache->retrieveContent(), + 'Asserts that retrieveContent() is returning text from cache' + ); + } + + public function outputDataProvider() { + + $language = Language::factory( 'en' ); + + $title = MockTitle::buildMockForMainNamespace( __METHOD__ . 'mock-subject' ); + + $subject = DIWikiPage::newFromTitle( $title ); + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $semanticData->expects( $this->atLeastOnce() ) + ->method( 'getSubject' ) + ->will( $this->returnValue( $subject ) ); + + $semanticData->expects( $this->atLeastOnce() ) + ->method( 'hasVisibleProperties' ) + ->will( $this->returnValue( true ) ); + + $semanticData->expects( $this->atLeastOnce() ) + ->method( 'getPropertyValues' ) + ->will( $this->returnValue( array( DIWikiPage::newFromTitle( $title ) ) ) ); + + $semanticData->expects( $this->atLeastOnce() ) + ->method( 'getProperties' ) + ->will( $this->returnValue( array( new DIProperty( __METHOD__ . 'property' ) ) ) ); + + #0 Simple factbox build, returning content + $title = MockTitle::buildMock( __METHOD__ . 'title-with-content' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_MAIN ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getPageLanguage' ) + ->will( $this->returnValue( $language ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 9098 ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( new \RequestContext() ) ); + + $provider[] = array( + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'outputPage' => $outputPage, + 'parserOutput' => $this->makeParserOutput( $semanticData ), + ), + array( + 'text' => $subject->getDBKey() + ) + ); + + #1 Disabled namespace, no return value expected + $title = MockTitle::buildMock( __METHOD__ . 'title-ns-disabled' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_MAIN ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getPageLanguage' ) + ->will( $this->returnValue( $language ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 90000 ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( new \RequestContext() ) ); + + $provider[] = array( + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => false ), + 'outputPage' => $outputPage, + 'parserOutput' => $this->makeParserOutput( $semanticData ), + ), + array( + 'text' => '' + ) + ); + + // #2 Specialpage, no return value expected + $title = MockTitle::buildMock( __METHOD__ . 'mock-specialpage' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getPageLanguage' ) + ->will( $this->returnValue( $language ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isSpecialPage' ) + ->will( $this->returnValue( true ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( new \RequestContext() ) ); + + $provider[] = array( + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'outputPage' => $outputPage, + 'parserOutput' => $this->makeParserOutput( $semanticData ), + ), + array( + 'text' => '' + ) + ); + + // #3 Redirect, no return value expected + $title = MockTitle::buildMock( __METHOD__ . 'mock-redirect' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getPageLanguage' ) + ->will( $this->returnValue( $language ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isRedirect' ) + ->will( $this->returnValue( true ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( new \RequestContext() ) ); + + $provider[] = array( + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'outputPage' => $outputPage, + 'parserOutput' => $this->makeParserOutput( $semanticData ), + ), + array( + 'text' => '' + ) + ); + + // #4 Oldid + $title = MockTitle::buildMockForMainNamespace( __METHOD__ . 'mock-oldid' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getPageLanguage' ) + ->will( $this->returnValue( $language ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $context = new \RequestContext( ); + $context->setRequest( new \FauxRequest( array( 'oldid' => 9001 ), true ) ); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( $context ) ); + + $provider[] = array( + array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'outputPage' => $outputPage, + 'parserOutput' => $this->makeParserOutput( $semanticData ), + ), + array( + 'text' => $subject->getDBKey() + ) + ); + + return $provider; + } + + protected function makeParserOutput( $data ) { + + $parserOutput = new ParserOutput(); + + if ( method_exists( $parserOutput, 'setExtensionData' ) ) { + $parserOutput->setExtensionData( 'smwdata', $data ); + } else { + $parserOutput->mSMWData = $data; + } + + return $parserOutput; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ParserAfterTidyTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ParserAfterTidyTest.php new file mode 100644 index 00000000..d201f569 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ParserAfterTidyTest.php @@ -0,0 +1,267 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\Tests\Util\SemanticDataValidator; +use SMW\Tests\Util\ParserFactory; +use SMW\Tests\Util\Mock\MockTitle; + +use SMW\MediaWiki\Hooks\ArticlePurge; +use SMW\MediaWiki\Hooks\ParserAfterTidy; + +use SMW\Application; +use SMW\Settings; + +use Title; + +/** + * @covers \SMW\MediaWiki\Hooks\ParserAfterTidy + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class ParserAfterTidyTest extends \PHPUnit_Framework_TestCase { + + private $semanticDataValidator; + private $application; + private $parserFactory; + + protected function setUp() { + parent::setUp(); + + $this->semanticDataValidator = new SemanticDataValidator(); + $this->application = Application::getInstance(); + $this->parserFactory = new ParserFactory(); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $parser = $this->getMockBuilder( 'Parser' ) + ->disableOriginalConstructor() + ->getMock(); + + $text = ''; + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\ParserAfterTidy', + new ParserAfterTidy( $parser, $text ) + ); + } + + private function newMockCacheHandler( $id, $status ) { + + $cacheHandler = $this->getMockBuilder( 'SMW\CacheHandler' ) + ->disableOriginalConstructor() + ->getMock(); + + $cacheHandler->expects( $this->any() ) + ->method( 'setKey' ) + ->with( $this->equalTo( ArticlePurge::newCacheId( $id ) ) ); + + $cacheHandler->expects( $this->any() ) + ->method( 'get' ) + ->will( $this->returnValue( $status ) ); + + return $cacheHandler; + } + + /** + * @dataProvider titleDataProvider + */ + public function testProcess( $parameters ) { + + $settings = Settings::newFromArray( array( + 'smwgCacheType' => 'hash', + 'smwgEnableUpdateJobs' => false + ) ); + + $this->application->registerObject( 'Settings', $settings ); + $this->application->registerObject( 'Store', $parameters['store'] ); + + $this->application->registerObject( + 'CacheHandler', + $this->newMockCacheHandler( $parameters['title']->getArticleID(), $parameters['cache'] ) + ); + + $parser = $this->parserFactory->newFromTitle( $parameters['title'] ); + + $parser->getOutput()->setProperty( + 'smw-semanticdata-status', + $parameters['data-status'] + ); + + $text = ''; + + $instance = new ParserAfterTidy( $parser, $text ); + + $this->assertTrue( $instance->process() ); + } + + public function testSemanticDataParserOuputUpdateIntegration() { + + $settings = Settings::newFromArray( array( + 'smwgCacheType' => 'hash', + 'smwgEnableUpdateJobs' => false, + 'smwgUseCategoryHierarchy' => false, + 'smwgCategoriesAsInstances' => true, + 'smwgShowHiddenCategories' => true + ) ); + + $this->application->registerObject( 'Settings', $settings ); + + $text = ''; + $title = Title::newFromText( __METHOD__ ); + + $parser = $this->parserFactory->newFromTitle( $title ); + + $parser->getOutput()->addCategory( 'Foo', 'Foo' ); + $parser->getOutput()->addCategory( 'Bar', 'Bar' ); + $parser->getOutput()->setProperty( 'smw-semanticdata-status', true ); + + $instance = new ParserAfterTidy( $parser, $text ); + $this->assertTrue( $instance->process() ); + + $expected = array( + 'propertyCount' => 2, + 'propertyKeys' => array( '_INST', '_SKEY' ), + 'propertyValues' => array( 'Foo', 'Bar', $title->getText() ), + ); + + $parserData = $this->application->newParserData( + $title, + $parser->getOutput() + ); + + $this->semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $parserData->getSemanticData() + ); + } + + public function titleDataProvider() { + + #0 Runs store update + $store = $this->getMockBuilder( 'SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $store->expects( $this->atLeastOnce() ) + ->method( 'updateData' ); + + $title = MockTitle::buildMock( __METHOD__ ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_MAIN ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'inNamespace' ) + ->will( $this->returnValue( false ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 5001 ) ); + + $provider[] = array( + array( + 'store' => $store, + 'title' => $title, + 'cache' => true, + 'data-status' => true + ) + ); + + #1 No cache entry, no store update + $store = $this->getMockBuilder( 'SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $store->expects( $this->never() ) + ->method( 'updateData' ); + + $title = MockTitle::buildMock( __METHOD__ ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_MAIN ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'inNamespace' ) + ->will( $this->returnValue( false ) ); + + $provider[] = array( + array( + 'store' => $store, + 'title' => $title, + 'cache' => false, + 'data-status' => true + ) + ); + + #2 SpecialPage, no store update + $store = $this->getMockBuilder( 'SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $store->expects( $this->never() ) + ->method( 'updateData' ); + + $title = MockTitle::buildMock( __METHOD__ ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isSpecialPage' ) + ->will( $this->returnValue( true ) ); + + $provider[] = array( + array( + 'store' => $store, + 'title' => $title, + 'cache' => false, + 'data-status' => true + ) + ); + + #3 NS_FILE, no store update + $store = $this->getMockBuilder( 'SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $store->expects( $this->never() ) + ->method( 'updateData' ); + + $title = MockTitle::buildMock( __METHOD__ ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'inNamespace' ) + ->will( $this->returnValue( true ) ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_FILE ) ); + + $provider[] = array( + array( + 'store' => $store, + 'title' => $title, + 'cache' => true, + 'data-status' => true + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ResourceLoaderGetConfigVarsTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ResourceLoaderGetConfigVarsTest.php new file mode 100644 index 00000000..4e101446 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ResourceLoaderGetConfigVarsTest.php @@ -0,0 +1,42 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\MediaWiki\Hooks\ResourceLoaderGetConfigVars; + +/** + * @covers \SMW\MediaWiki\Hooks\ResourceLoaderGetConfigVars + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class ResourceLoaderGetConfigVarsTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $vars = array(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\ResourceLoaderGetConfigVars', + new ResourceLoaderGetConfigVars( $vars ) + ); + } + + public function testProcess() { + + $vars = array(); + + $instance = new ResourceLoaderGetConfigVars( $vars ); + $instance->process(); + + $this->assertArrayHasKey( 'smw-config', $vars ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ResourceLoaderTestModulesTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ResourceLoaderTestModulesTest.php new file mode 100644 index 00000000..542d7ecf --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ResourceLoaderTestModulesTest.php @@ -0,0 +1,50 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\MediaWiki\Hooks\ResourceLoaderTestModules; + +/** + * @covers \SMW\MediaWiki\Hooks\ResourceLoaderTestModules + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class ResourceLoaderTestModulesTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $resourceLoader = $this->getMockBuilder( '\ResourceLoader' ) + ->disableOriginalConstructor() + ->getMock(); + + $testModules = array(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\ResourceLoaderTestModules', + new ResourceLoaderTestModules( $resourceLoader, $testModules, '', '' ) + ); + } + + public function testProcess() { + + $resourceLoader = $this->getMockBuilder( '\ResourceLoader' ) + ->disableOriginalConstructor() + ->getMock(); + + $testModules = array(); + + $instance = new ResourceLoaderTestModules( $resourceLoader, $testModules, '', '' ); + $instance->process(); + + $this->assertArrayHasKey( 'ext.smw.tests', $testModules['qunit'] ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/SkinAfterContentTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/SkinAfterContentTest.php new file mode 100644 index 00000000..ee6e4428 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/SkinAfterContentTest.php @@ -0,0 +1,259 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\Tests\Util\Mock\MockTitle; + +use SMW\MediaWiki\Hooks\SkinAfterContent; +use SMW\Application; +use SMW\Settings; + +/** + * @covers \SMW\MediaWiki\Hooks\SkinAfterContent + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SkinAfterContentTest extends \PHPUnit_Framework_TestCase { + + private $application; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + + $settings = Settings::newFromArray( array( + 'smwgFactboxUseCache' => true, + 'smwgCacheType' => 'hash' + ) ); + + $this->application->registerObject( 'Settings', $settings ); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $data = ''; + + $skin = $this->getMockBuilder( '\Skin' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\SkinAfterContent', + new SkinAfterContent( $data, $skin ) + ); + } + + /** + * @dataProvider outputDataProvider + */ + public function testProcessFactboxPresenterIntegration( $parameters, $expected ) { + + $data = ''; + + $instance = new SkinAfterContent( $data, $parameters['skin'] ); + + // Inject fake content into the FactboxPresenter + if ( isset( $parameters['title'] ) ) { + + $factboxCache = $this->application + ->newFactboxBuilder() + ->newFactboxCache( $parameters['skin']->getOutput() ); + + $resultMapper = $factboxCache->newResultMapper( $parameters['title']->getArticleID() ); + $resultMapper->recache( array( + 'revId' => null, + 'text' => $parameters['text'] + ) ); + } + + $this->assertTrue( $instance->process() ); + + $this->assertEquals( + $expected['text'], + $data + ); + } + + public function outputDataProvider() { + + $text = __METHOD__ . 'text-0'; + + #0 Retrive content from outputPage property + $title = MockTitle::buildMock( __METHOD__ . 'from-property' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 10001 ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $outputPage->mSMWFactboxText = $text; + + $skin = $this->getMockBuilder( '\Skin' ) + ->disableOriginalConstructor() + ->getMock(); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( null ) ); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getOutput' ) + ->will( $this->returnValue( $outputPage ) ); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( new \RequestContext() ) ); + + $provider[] = array( + array( 'skin' => $skin ), + array( 'text' => $text ) + ); + + #1 Retrive content from cache + $title = MockTitle::buildMock( __METHOD__ . 'from-cache' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 10002 ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $text = __METHOD__ . 'text-1'; + + $skin = $this->getMockBuilder( '\Skin' ) + ->disableOriginalConstructor() + ->getMock(); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getOutput' ) + ->will( $this->returnValue( $outputPage ) ); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( new \RequestContext() ) ); + + $provider[] = array( + array( 'skin' => $skin, 'text' => $text, 'title' => $outputPage->getTitle() ), + array( 'text' => $text ) + ); + + + // #2 Special page + $text = __METHOD__ . 'text-2'; + + $title = MockTitle::buildMock( __METHOD__ . 'specialpage' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'isSpecialPage' ) + ->will( $this->returnValue( true ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $outputPage->mSMWFactboxText = $text; + + $skin = $this->getMockBuilder( '\Skin' ) + ->disableOriginalConstructor() + ->getMock(); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getOutput' ) + ->will( $this->returnValue( $outputPage ) ); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( new \RequestContext() ) ); + + $provider[] = array( + array( 'skin' => $skin, 'text' => $text ), + array( 'text' => '' ) + ); + + // #3 "edit" request + $text = __METHOD__ . 'text-3'; + + $title = MockTitle::buildMock( __METHOD__ . 'edit-request' ); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getArticleID' ) + ->will( $this->returnValue( 10003 ) ); + + $outputPage = $this->getMockBuilder( '\OutputPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $outputPage->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $outputPage->mSMWFactboxText = $text; + + $skin = $this->getMockBuilder( '\Skin' ) + ->disableOriginalConstructor() + ->getMock(); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getOutput' ) + ->will( $this->returnValue( $outputPage ) ); + + $context = new \RequestContext( ); + $context->setRequest( new \FauxRequest( array( 'action' => 'edit' ), true ) ); + + $skin->expects( $this->atLeastOnce() ) + ->method( 'getContext' ) + ->will( $this->returnValue( $context ) ); + + $provider[] = array( + array( 'skin' => $skin, 'text' => $text ), + array( 'text' => $text ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/SkinTemplateNavigationTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/SkinTemplateNavigationTest.php new file mode 100644 index 00000000..12a6de76 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/SkinTemplateNavigationTest.php @@ -0,0 +1,78 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\MediaWiki\Hooks\SkinTemplateNavigation; + +/** + * @covers \SMW\MediaWiki\Hooks\SkinTemplateNavigation + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class SkinTemplateNavigationTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $skinTemplate = $this->getMockBuilder( '\SkinTemplate' ) + ->disableOriginalConstructor() + ->getMock(); + + $links = array(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\SkinTemplateNavigation', + new SkinTemplateNavigation( $skinTemplate, $links ) + ); + } + + public function testProcess() { + + $title = $this->getMockBuilder( '\Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $message = $this->getMockBuilder( '\Message' ) + ->disableOriginalConstructor() + ->getMock(); + + $user = $this->getMockBuilder( '\User' ) + ->disableOriginalConstructor() + ->getMock(); + + $user->expects( $this->atLeastOnce() ) + ->method( 'isAllowed' ) + ->will( $this->returnValue( true ) ); + + $skinTemplate = $this->getMockBuilder( '\SkinTemplate' ) + ->disableOriginalConstructor() + ->getMock(); + + $skinTemplate->expects( $this->atLeastOnce() ) + ->method( 'getUser' ) + ->will( $this->returnValue( $user ) ); + + $skinTemplate->expects( $this->atLeastOnce() ) + ->method( 'msg' ) + ->will( $this->returnValue( $message ) ); + + $skinTemplate->expects( $this->atLeastOnce() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( $title ) ); + + $links = array(); + + $instance = new SkinTemplateNavigation( $skinTemplate, $links ); + $instance->process(); + + $this->assertArrayHasKey( 'purge', $links['actions'] ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/SpecialStatsAddExtraTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/SpecialStatsAddExtraTest.php new file mode 100644 index 00000000..15225799 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/SpecialStatsAddExtraTest.php @@ -0,0 +1,178 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\MediaWiki\Hooks\SpecialStatsAddExtra; +use SMW\Application; +use SMW\StoreFactory; + +/** + * @covers \SMW\MediaWiki\Hooks\SpecialStatsAddExtra + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SpecialStatsAddExtraTest extends \PHPUnit_Framework_TestCase { + + protected function tearDown() { + Application::clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $userLanguage = $this->getMockBuilder( '\Language' ) + ->disableOriginalConstructor() + ->getMock(); + + $extraStats = array(); + $version = ''; + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\SpecialStatsAddExtra', + new SpecialStatsAddExtra( $extraStats, $version, $userLanguage ) + ); + } + + /** + * @dataProvider statisticsDataProvider + */ + public function testProcessForMockedStore( $setup, $expected ) { + + $formatNumReturnValue = isset( $setup['statistics']['PROPUSES'] ) ? $setup['statistics']['PROPUSES'] : ''; + + $userLanguage = $this->getMockBuilder( '\Language' ) + ->disableOriginalConstructor() + ->getMock(); + + $userLanguage->expects( $this->any() ) + ->method( 'formatNum' ) + ->will( $this->returnValue( $formatNumReturnValue ) ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $store->expects( $this->atLeastOnce() ) + ->method( 'getStatistics' ) + ->will( $this->returnValue( $setup['statistics'] ) ); + + Application::getInstance()->registerObject( 'Store', $store ); + + $extraStats = $setup['extraStats']; + $version = $setup['version']; + + $instance = new SpecialStatsAddExtra( $extraStats, $version, $userLanguage ); + + $this->assertTrue( $instance->process() ); + + $this->assertTrue( + $this->matchArray( $extraStats, $expected['statistics'] ) + ); + } + + public function testProcessOnSQLStore() { + + $userLanguage = $this->getMockBuilder( '\Language' ) + ->disableOriginalConstructor() + ->getMock(); + + Application::getInstance()->registerObject( 'Store', StoreFactory::getStore() ); + + $extraStats = array(); + $version = '1.21'; + + $instance = new SpecialStatsAddExtra( $extraStats, $version, $userLanguage ); + + $this->assertTrue( $instance->process() ); + + // This is a "cheap" check against the SQLStore as it could return any + // value therefore we use a message key as only known constant to verify + // that the matching process was successful + $this->assertTrue( + $this->matchArray( $extraStats, 'smw-statistics-property-instance' ) + ); + } + + public function matchArray( array $matcher, $searchValue ) { + + foreach ( $matcher as $key => $value ) { + + if ( $searchValue === $key || $searchValue === $value ) { + return true; + }; + + if ( is_array( $value ) ) { + return $this->matchArray( $value, $searchValue ); + }; + } + + return $searchValue !== null ? false : true; + } + + public function statisticsDataProvider() { + + $input = array( + 'PROPUSES' => 1001 + ); + + #0 Legacy + $provider[] = array( + array( + 'version' => '1.20', + 'extraStats' => array(), + 'statistics' => $input + ), + array( + 'statistics' => 1001 + ) + ); + + #1 Legacy - unknown + $provider[] = array( + array( + 'version' => '1.20', + 'extraStats' => array(), + 'statistics' => array( 'Yeey' => 2002 ) + ), + array( + 'statistics' => null + ) + ); + + #2 MW 1.21+ + $provider[] = array( + array( + 'version' => '1.21', + 'extraStats' => array(), + 'statistics' => $input + ), + array( + 'statistics' => 1001 + ) + ); + + #3 MW 1.21+ - unknown + $provider[] = array( + array( + 'version' => '1.21', + 'extraStats' => array(), + 'statistics' => array( 'Quuxy' => 2002 ) + ), + array( + 'statistics' => null + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/TitleIsAlwaysKnownTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/TitleIsAlwaysKnownTest.php new file mode 100644 index 00000000..f970afb0 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/TitleIsAlwaysKnownTest.php @@ -0,0 +1,72 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\MediaWiki\Hooks\TitleIsAlwaysKnown; + +/** + * @covers \SMW\MediaWiki\Hooks\TitleIsAlwaysKnown + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class TitleIsAlwaysKnownTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $title = $this->getMockBuilder( '\Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $result = ''; + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\TitleIsAlwaysKnown', + new TitleIsAlwaysKnown( $title, $result ) + ); + } + + /** + * @dataProvider titleProvider + */ + public function testPerformUpdate( $namespace, $text, $expected ) { + + $title = $this->getMockBuilder( '\Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $title->expects( $this->atLeastOnce() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( $namespace ) ); + + $title->expects( $this->any() ) + ->method( 'getText' ) + ->will( $this->returnValue( $text ) ); + + $result = ''; + + $instance = new TitleIsAlwaysKnown( $title, $result ); + $this->assertTrue( $instance->process() ); + + $this->assertEquals( $expected, $result ); + } + + public function titleProvider() { + + $provider = array( + array( SMW_NS_PROPERTY, 'Modification date', true ), + array( SMW_NS_PROPERTY, 'Foo', false ), + array( NS_MAIN, 'Modification date', false ), + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/TitleMoveCompleteTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/TitleMoveCompleteTest.php new file mode 100644 index 00000000..1d928de3 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/TitleMoveCompleteTest.php @@ -0,0 +1,95 @@ +<?php + +namespace SMW\Tests\MediaWiki\Hooks; + +use SMW\Tests\Util\Mock\MockTitle; +use SMW\Tests\Util\Mock\MockSuperUser; + +use SMW\MediaWiki\Hooks\TitleMoveComplete; +use SMW\Application; +use SMW\Settings; + +/** + * @covers \SMW\MediaWiki\Hooks\TitleMoveComplete + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class TitleMoveCompleteTest extends \PHPUnit_Framework_TestCase { + + private $application; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $oldTitle = MockTitle::buildMock( 'old' ); + $newTitle = MockTitle::buildMock( 'new' ); + + $instance = new TitleMoveComplete( + $oldTitle, + $newTitle, + new MockSuperUser(), + 0, + 0 + ); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Hooks\TitleMoveComplete', + $instance + ); + } + + public function testProcess() { + + $oldTitle = MockTitle::buildMock( 'old' ); + $newTitle = MockTitle::buildMock( 'new' ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $store->expects( $this->once() ) + ->method( 'changeTitle' ) + ->with( + $this->equalTo( $oldTitle ), + $this->equalTo( $newTitle ), + $this->anything(), + $this->anything() ); + + $this->application->registerObject( 'Settings', Settings::newFromArray( array( + 'smwgCacheType' => 'hash', + 'smwgAutoRefreshOnPageMove' => true, + ) ) ); + + $this->application->registerObject( 'Store', $store ); + + $instance = new TitleMoveComplete( + $oldTitle, + $newTitle, + new MockSuperUser(), + 0, + 0 + ); + + $this->assertTrue( $instance->process() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/DeleteSubjectJobTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/DeleteSubjectJobTest.php new file mode 100644 index 00000000..012acc13 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/DeleteSubjectJobTest.php @@ -0,0 +1,221 @@ +<?php + +namespace SMW\Tests\MediaWiki\Jobs; + +use SMW\MediaWiki\Jobs\DeleteSubjectJob; +use SMW\DIWikiPage; +use SMW\SemanticData; +use SMW\Settings; +use SMW\Application; + +use Title; +use ReflectionClass; + +/** + * @covers \SMW\MediaWiki\Jobs\DeleteSubjectJob + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9.1 + * + * @author mwjames + */ +class DeleteSubjectJobTest extends \PHPUnit_Framework_TestCase { + + /* @var boolean */ + protected $deleteSubjectWasCalled = false; + + /* @var Title|null */ + protected $titlePlannedToBeDeleted = null; + + public function testCanConstruct() { + + $title = $this->getMockBuilder( 'Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + 'SMW\MediaWiki\Jobs\DeleteSubjectJob', + new DeleteSubjectJob( $title ) + ); + } + + /** + * @dataProvider jobDefinitionProvider + */ + public function testExecuteOnMockStore( $parameters, $expected ) { + + $this->titlePlannedToBeDeleted = $parameters['title']; + + $instance = $this->acquireInstance( + $parameters['title'], + $parameters['settings'] + ); + + $this->assertTrue( $instance->execute() ); + + $this->assertEquals( + $expected['deleteSubjectWasCalled'], + $this->deleteSubjectWasCalled + ); + + $this->assertJobsAndJobCount( $expected['jobCount'], $instance ); + + unset( $this->deleteSubjectWasCalled ); + unset( $this->titlePlannedToBeDeleted ); + } + + public function mockStoreDeleteSubjectCallback( Title $title ) { + $this->deleteSubjectWasCalled = $this->titlePlannedToBeDeleted === $title; + } + + public function jobDefinitionProvider() { + + $provider = array(); + + #0 + $provider[] = array( + array( + 'title' => Title::newFromText( __METHOD__, NS_MAIN ), + 'settings' => array( + 'smwgEnableUpdateJobs' => true, + 'smwgDeleteSubjectAsDeferredJob' => false, + 'smwgDeleteSubjectWithAssociatesRefresh' => false + ) + ), + array( + 'jobCount' => 0, + 'deleteSubjectWasCalled' => true + ) + ); + + #1 + $provider[] = array( + array( + 'title' => Title::newFromText( __METHOD__, NS_MAIN ), + 'settings' => array( + 'smwgEnableUpdateJobs' => true, + 'smwgDeleteSubjectAsDeferredJob' => true, + 'smwgDeleteSubjectWithAssociatesRefresh' => true + ) + ), + array( + 'jobCount' => 1, + 'deleteSubjectWasCalled' => true + ) + ); + + #2 + $provider[] = array( + array( + 'title' => Title::newFromText( __METHOD__, NS_MAIN ), + 'settings' => array( + 'smwgEnableUpdateJobs' => false, + 'smwgDeleteSubjectAsDeferredJob' => true, + 'smwgDeleteSubjectWithAssociatesRefresh' => true + ) + ), + array( + 'jobCount' => 0, + 'deleteSubjectWasCalled' => true + ) + ); + + #3 + $provider[] = array( + array( + 'title' => Title::newFromText( __METHOD__, NS_MAIN ), + 'settings' => array( + 'smwgEnableUpdateJobs' => false, + 'smwgDeleteSubjectAsDeferredJob' => true, + 'smwgDeleteSubjectWithAssociatesRefresh' => false + ) + ), + array( + 'jobCount' => 0, + 'deleteSubjectWasCalled' => true + ) + ); + + return $provider; + } + + protected function assertJobsAndJobCount( $count, $instance ) { + + $reflector = new ReflectionClass( 'SMW\MediaWiki\Jobs\DeleteSubjectJob' ); + $jobs = $reflector->getProperty( 'jobs' ); + $jobs->setAccessible( true ); + + $actualJobs = $jobs->getValue( $instance ); + + $this->assertInternalType( 'array', $actualJobs ); + $this->assertCount( $count, $actualJobs ); + + foreach ( $actualJobs as $job ) { + $this->assertEquals( 'SMW\DeleteSubjectJob', $job->getType() ); + $this->assertTrue( $job->hasParameter( 'withAssociates' ) ); + $this->assertTrue( $job->hasParameter( 'asDeferredJob' ) ); + $this->assertTrue( $job->hasParameter( 'semanticData' ) ); + } + } + + /** + * @return DeleteSubjectJob + */ + private function acquireInstance( Title $title = null, $settings = array() ) { + + if ( $title === null ) { + $title = Title::newFromText( __METHOD__ ); + } + + $defaultSettings = array( + 'smwgCacheType' => 'hash', + 'smwgEnableUpdateJobs' => false, + 'smwgDeleteSubjectAsDeferredJob' => false, + 'smwgDeleteSubjectWithAssociatesRefresh' => false + ); + + $settings = Settings::newFromArray( array_merge( $defaultSettings, $settings ) ); + + $semanticData = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + + $mockStore = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( 'deleteSubject', 'getSemanticData', 'getProperties', 'getInProperties' ) ) + ->getMockForAbstractClass(); + + $mockStore->expects( $this->once() ) + ->method( 'deleteSubject' ) + ->will( $this->returnCallback( array( $this, 'mockStoreDeleteSubjectCallback' ) ) ); + + $mockStore->expects( $this->any() ) + ->method( 'getSemanticData' ) + ->will( $this->returnValue( $semanticData ) ); + + $mockStore->expects( $this->any() ) + ->method( 'getProperties' ) + ->will( $this->returnValue( array() ) ); + + $mockStore->expects( $this->any() ) + ->method( 'getInProperties' ) + ->will( $this->returnValue( array() ) ); + + Application::getInstance()->registerObject( 'Store', $mockStore ); + Application::getInstance()->registerObject( 'Settings', $settings ); + + $parameters = array( + 'asDeferredJob' => $settings->get( 'smwgDeleteSubjectAsDeferredJob' ), + 'withAssociates' => $settings->get( 'smwgDeleteSubjectWithAssociatesRefresh' ) + ); + + $instance = new DeleteSubjectJob( $title, $parameters ); + $instance->setJobQueueEnabledState( false ); + + return $instance; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/JobFactoryTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/JobFactoryTest.php new file mode 100644 index 00000000..5e9247e8 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/JobFactoryTest.php @@ -0,0 +1,52 @@ +<?php + +namespace SMW\Tests\MediaWiki\Jobs; + +use SMW\MediaWiki\Jobs\JobFactory; + +use Title; + +/** + * @covers \SMW\MediaWiki\Jobs\JobFactory + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class JobFactoryTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\MediaWiki\Jobs\JobFactory', + new JobFactory() + ); + } + + public function testUpdateJob() { + + $instance = new JobFactory(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Jobs\UpdateJob', + $instance->newUpdateJob( Title::newFromText( __METHOD__ ) ) + ); + } + + public function testUpdateDispatcherJob() { + + $instance = new JobFactory(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\Jobs\UpdateDispatcherJob', + $instance->newUpdateDispatcherJob( Title::newFromText( __METHOD__ ) ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/RefreshJobTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/RefreshJobTest.php new file mode 100644 index 00000000..6a357994 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/RefreshJobTest.php @@ -0,0 +1,182 @@ +<?php + +namespace SMW\Tests\MediaWiki\Jobs; + +use SMW\MediaWiki\Jobs\RefreshJob; +use SMW\Application; + +use Title; + +/** + * @covers \SMW\MediaWiki\Jobs\RefreshJob + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class RefreshJobTest extends \PHPUnit_Framework_TestCase { + + /** @var integer */ + protected $controlRefreshDataIndex; + + private $application; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->application->registerObject( 'Store', $store ); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $title = $this->getMockBuilder( 'Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + 'SMW\MediaWiki\Jobs\RefreshJob', + new RefreshJob( $title ) + ); + + // FIXME Delete SMWRefreshJob assertion after all + // references to SMWRefreshJob have been removed + $this->assertInstanceOf( + 'SMW\MediaWiki\Jobs\RefreshJob', + new \SMWRefreshJob( $title ) + ); + } + + /** + * @dataProvider parameterDataProvider + */ + public function testRunJobOnMockStore( $parameters, $expected ) { + + $title = Title::newFromText( __METHOD__ ); + + $expectedToRun = $expected['spos'] === null ? $this->never() : $this->once(); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( 'refreshData' ) ) + ->getMockForAbstractClass(); + + $store->expects( $expectedToRun ) + ->method( 'refreshData' ) + ->will( $this->returnCallback( array( $this, 'refreshDataCallback' ) ) ); + + $this->application->registerObject( 'Store', $store ); + + $instance = new RefreshJob( $title, $parameters ); + $instance->setJobQueueEnabledState( false ); + + $this->assertTrue( $instance->run() ); + + $this->assertEquals( + $expected['progress'], + $instance->getProgress(), + "Asserts that the getProgress() returns {$expected['progress']}" + ); + + $this->assertEquals( + $expected['spos'], + $this->controlRefreshDataIndex, + "Asserts that the refreshData() received a spos {$expected['spos']}" + ); + + unset( $this->controlRefreshDataIndex ); + } + + /** + * @return array + */ + public function parameterDataProvider() { + + $provider = array(); + + // #0 Empty + $provider[] = array( + array(), + array( + 'progress' => 0, + 'spos' => null + ) + ); + + // #1 Initial + $provider[] = array( + array( + 'spos' => 1, + 'prog' => 0, + 'rc' => 1 + ), + array( + 'progress' => 0, + 'spos' => 1 + ) + ); + + // #2 + $provider[] = array( + array( + 'spos' => 1, + 'run' => 1, + 'prog' => 10, + 'rc' => 1 + ), + array( + 'progress' => 10, + 'spos' => 1 + ) + ); + + // #3 Initiates another run from the beginning + $provider[] = array( + array( + 'spos' => 0, + 'run' => 1, + 'prog' => 10, + 'rc' => 2 + ), + array( + 'progress' => 5, + 'spos' => 0 + ) + ); + + return $provider; + + } + + /** + * @see Store::refreshData + * + * @since 1.9 + * + * @param integer $index + * @param integer $count + * @param mixed $namespaces Array or false + * @param boolean $usejobs + */ + public function refreshDataCallback( &$index, $count, $namespaces ) { + $this->controlRefreshDataIndex = $index; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/UpdateDispatcherJobTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/UpdateDispatcherJobTest.php new file mode 100644 index 00000000..cf349d4c --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/UpdateDispatcherJobTest.php @@ -0,0 +1,308 @@ +<?php + +namespace SMW\Tests\MediaWiki\Jobs; + +use SMW\MediaWiki\Jobs\UpdateDispatcherJob; +use SMW\Application; +use SMW\DIProperty; +use SMW\DIWikiPage; +use SMW\SemanticData; +use SMW\Settings; + +use Title; + +/** + * @covers \SMW\MediaWiki\Jobs\UpdateDispatcherJob + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class UpdateDispatcherJobTest extends \PHPUnit_Framework_TestCase { + + protected $expectedProperty; + protected $expectedSubjects; + + private $application; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + + $settings = Settings::newFromArray( array( + 'smwgCacheType' => 'hash', + 'smwgEnableUpdateJobs' => false + ) ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->application->registerObject( 'Store', $store ); + $this->application->registerObject( 'Settings', $settings ); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $title = $this->getMockBuilder( 'Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + 'SMW\MediaWiki\Jobs\UpdateDispatcherJob', + new UpdateDispatcherJob( $title ) + ); + } + + public function testPushToJobQueue() { + + $title = $this->getMockBuilder( 'Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new UpdateDispatcherJob( $title, array() ); + $instance->setJobQueueEnabledState( false ); + + $this->assertNull( $instance->pushToJobQueue() ); + } + + public function testJobRunOnMainNamespace() { + + $title = Title::newFromText( __METHOD__, NS_MAIN ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( + 'getProperties', + 'getInProperties' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->any() ) + ->method( 'getProperties' ) + ->will( $this->returnValue( array() ) ); + + $store->expects( $this->any() ) + ->method( 'getInProperties' ) + ->will( $this->returnValue( array() ) ); + + $this->application->registerObject( 'Store', $store ); + + $instance = new UpdateDispatcherJob( $title, array() ); + $instance->setJobQueueEnabledState( false ); + + $this->assertTrue( $instance->run() ); + } + + public function testJobRunOnPropertyNamespace() { + + $title = Title::newFromText( __METHOD__, SMW_NS_PROPERTY ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( + 'getProperties', + 'getInProperties', + 'getAllPropertySubjects', + 'getPropertySubjects' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->any() ) + ->method( 'getProperties' ) + ->will( $this->returnValue( array() ) ); + + $store->expects( $this->any() ) + ->method( 'getInProperties' ) + ->will( $this->returnValue( array() ) ); + + $store->expects( $this->any() ) + ->method( 'getAllPropertySubjects' ) + ->will( $this->returnValue( array() ) ); + + $store->expects( $this->any() ) + ->method( 'getPropertySubjects' ) + ->will( $this->returnValue( array() ) ); + + $this->application->registerObject( 'Store', $store ); + + $instance = new UpdateDispatcherJob( $title, array() ); + $instance->setJobQueueEnabledState( false ); + + $this->assertTrue( $instance->run() ); + } + + /** + * @dataProvider subjectDataProvider + */ + public function testRunJobOnMockWithOutParameters( $setup, $expected ) { + + $this->expectedProperty = $setup['property']; + $this->expectedSubjects = $setup['subjects']; + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( + 'getAllPropertySubjects', + 'getProperties', + 'getInProperties', + 'getPropertySubjects' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->any() ) + ->method( 'getAllPropertySubjects' ) + ->will( $this->returnCallback( array( $this, 'mockStoreAllPropertySubjectsCallback' ) ) ); + + $store->expects( $this->any() ) + ->method( 'getProperties' ) + ->will( $this->returnValue( $setup['properties'] ) ); + + $store->expects( $this->any() ) + ->method( 'getInProperties' ) + ->will( $this->returnValue( $setup['properties'] ) ); + + $store->expects( $this->any() ) + ->method( 'getPropertySubjects' ) + ->will( $this->returnValue( array() ) ); + + $this->application->registerObject( 'Store', $store ); + + $instance = new UpdateDispatcherJob( $setup['title'], array() ); + $instance->setJobQueueEnabledState( false ); + $instance->run(); + + $this->assertEquals( + $expected['count'], + $instance->getJobCount() + ); + } + + /** + * @dataProvider subjectDataProvider + */ + public function testRunJobOnMockWithParameters( $setup, $expected ) { + + $semanticData = $this->application->newSerializerFactory()->serialize( + new SemanticData( DIWikiPage::newFromTitle( $setup['title'] ) + ) ); + + $additionalJobQueueParameters = array( + 'semanticData' => $semanticData + ); + + $this->expectedProperty = $setup['property']; + $this->expectedSubjects = $setup['subjects']; + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( + 'getAllPropertySubjects', + 'getProperties', + 'getInProperties', + 'getPropertySubjects' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->any() ) + ->method( 'getAllPropertySubjects' ) + ->will( $this->returnCallback( array( $this, 'mockStoreAllPropertySubjectsCallback' ) ) ); + + $store->expects( $this->any() ) + ->method( 'getProperties' ) + ->will( $this->returnValue( $setup['properties'] ) ); + + $store->expects( $this->any() ) + ->method( 'getInProperties' ) + ->will( $this->returnValue( $setup['properties'] ) ); + + $store->expects( $this->any() ) + ->method( 'getPropertySubjects' ) + ->will( $this->returnValue( array() ) ); + + $this->application->registerObject( 'Store', $store ); + + $instance = new UpdateDispatcherJob( $setup['title'], $additionalJobQueueParameters ); + $instance->setJobQueueEnabledState( false ); + $instance->run(); + + $this->assertEquals( + $expected['count'], + $instance->getJobCount() + ); + } + + public function subjectDataProvider() { + + $provider = array(); + + $duplicate = $this->makeSubjectFromText( 'Foo' ); + + $subjects = array( + $duplicate, + $this->makeSubjectFromText( 'Bar' ), + $this->makeSubjectFromText( 'Baz' ), + $duplicate, + $this->makeSubjectFromText( 'Yon' ) + ); + + $count = count( $subjects ) - 1; // eliminate duplicate count + $title = Title::newFromText( __METHOD__, SMW_NS_PROPERTY ); + $property = DIProperty::newFromUserLabel( $title->getText() ); + + $provider[] = array( + array( + 'title' => $title, + 'subjects' => $subjects, + 'property' => $property, + 'properties' => array() + ), + array( + 'count' => $count + ) + ); + + $title = Title::newFromText( __METHOD__, NS_MAIN ); + $property = DIProperty::newFromUserLabel( $title->getText() ); + + $provider[] = array( + array( + 'title' => $title, + 'subjects' => array( DIWikiPage::newFromTitle( $title ) ), + 'property' => $property, + 'properties' => array( $property ) + ), + array( + 'count' => 1 + ) + ); + + return $provider; + } + + /** + * Returns an array of DIWikiPage objects if the expected property + * and the argument property are identical + * + * @see Store::getAllPropertySubjects + * + * @return DIWikiPage[] + */ + public function mockStoreAllPropertySubjectsCallback( DIProperty $property, $requestoptions = null ) { + return $this->expectedProperty == $property ? $this->expectedSubjects : array(); + } + + protected function makeSubjectFromText( $text ) { + return DIWikiPage::newFromTitle( Title::newFromText( $text ) ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/UpdateJobTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/UpdateJobTest.php new file mode 100644 index 00000000..45e79ade --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/UpdateJobTest.php @@ -0,0 +1,175 @@ +<?php + +namespace SMW\Tests\MediaWiki\Jobs; + +use SMW\MediaWiki\Jobs\UpdateJob; +use SMW\Settings; +use SMW\Application; + +use Title; + +/** + * @covers \SMW\MediaWiki\Jobs\UpdateJob + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class UpdateJobTest extends \PHPUnit_Framework_TestCase { + + private $application; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + + $settings = Settings::newFromArray( array( + 'smwgCacheType' => 'hash', + 'smwgEnableUpdateJobs' => false + ) ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->application->registerObject( 'Store', $store ); + $this->application->registerObject( 'Settings', $settings ); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $title = $this->getMockBuilder( 'Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + 'SMW\MediaWiki\Jobs\UpdateJob', + new UpdateJob( $title ) + ); + + // FIXME Delete SMWUpdateJob assertion after all + // references to SMWUpdateJob have been removed + $this->assertInstanceOf( + 'SMW\MediaWiki\Jobs\UpdateJob', + new \SMWUpdateJob( $title ) + ); + } + + public function testJobWithMissingParserOutput() { + + $title = $this->getMockBuilder( 'Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $title->expects( $this->any() ) + ->method( 'exists' ) + ->will( $this->returnValue( true ) ); + + $instance = new UpdateJob( $title ); + $instance->setJobQueueEnabledState( false ); + + $this->assertFalse( $instance->run() ); + } + + public function testJobWithInvalidTitle() { + + $title = $this->getMockBuilder( 'Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $title->expects( $this->once() ) + ->method( 'exists' ) + ->will( $this->returnValue( false ) ); + + $this->application->registerObject( 'ContentParser', null ); + + $instance = new UpdateJob( $title ); + $instance->setJobQueueEnabledState( false ); + + $this->assertTrue( $instance->run() ); + } + + public function testJobWithNoRevisionAvailable() { + + $title = $this->getMockBuilder( 'Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $title->expects( $this->once() ) + ->method( 'exists' ) + ->will( $this->returnValue( true ) ); + + $contentParser = $this->getMockBuilder( '\SMW\ContentParser' ) + ->disableOriginalConstructor() + ->getMock(); + + $contentParser->expects( $this->once() ) + ->method( 'getOutput' ) + ->will( $this->returnValue( null ) ); + + $this->application->registerObject( 'ContentParser', $contentParser ); + + $instance = new UpdateJob( $title ); + $instance->setJobQueueEnabledState( false ); + + $this->assertFalse( $instance->run() ); + } + + public function testJobWithValidRevision() { + + $title = $this->getMockBuilder( 'Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $title->expects( $this->once() ) + ->method( 'getDBkey' ) + ->will( $this->returnValue( __METHOD__ ) ); + + $title->expects( $this->once() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( 0 ) ); + + $title->expects( $this->once() ) + ->method( 'exists' ) + ->will( $this->returnValue( true ) ); + + $contentParser = $this->getMockBuilder( '\SMW\ContentParser' ) + ->disableOriginalConstructor() + ->getMock(); + + $contentParser->expects( $this->atLeastOnce() ) + ->method( 'getOutput' ) + ->will( $this->returnValue( new \ParserOutput ) ); + + $this->application->registerObject( 'ContentParser', $contentParser ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( 'updateData' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->once() ) + ->method( 'updateData' ); + + $this->application->registerObject( 'Store', $store ); + + $instance = new UpdateJob( $title ); + $instance->setJobQueueEnabledState( false ); + + $this->assertTrue( $instance->run() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/LazyDBConnectionProviderTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/LazyDBConnectionProviderTest.php new file mode 100644 index 00000000..f5ba191b --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/LazyDBConnectionProviderTest.php @@ -0,0 +1,68 @@ +<?php + +namespace SMW\Tests\MediaWiki; + +use SMW\MediaWiki\LazyDBConnectionProvider; + +use DatabaseBase; +use ReflectionClass; + +/** + * @covers \SMW\MediaWiki\LazyDBConnectionProvider + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class LazyDBConnectionProviderTest extends \PHPUnit_Framework_TestCase { + + public function getClass() { + return '\SMW\MediaWiki\LazyDBConnectionProvider'; + } + + private function newInstance( $connectionId = DB_SLAVE, $groups = array(), $wiki = false ) { + return new LazyDBConnectionProvider( $connectionId, $groups, $wiki ); + } + + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + public function testGetAndReleaseConnection() { + + $instance = $this->newInstance( DB_SLAVE ); + $connection = $instance->getConnection(); + + $this->assertInstanceOf( 'DatabaseBase', $instance->getConnection() ); + + $this->assertTrue( + $instance->getConnection() === $connection, + 'Asserts that getConnection yields the same instance' + ); + + $instance->releaseConnection(); + + } + + public function testGetConnectionThrowsException() { + + $this->setExpectedException( 'RuntimeException' ); + + $instance = $this->newInstance(); + $reflector = new ReflectionClass( $this->getClass() ); + + $connection = $reflector->getProperty( 'connection' ); + $connection->setAccessible( true ); + $connection->setValue( $instance, 'invalid' ); + + $this->assertInstanceOf( 'DatabaseBase', $instance->getConnection() ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/MagicWordFinderTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/MagicWordFinderTest.php new file mode 100644 index 00000000..c7e9b09f --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/MagicWordFinderTest.php @@ -0,0 +1,122 @@ +<?php + +namespace SMW\Tests\MediaWiki; + +use SMW\MediaWiki\MagicWordFinder; + +use ParserOutput; + +/** + * @covers \SMW\MediaWiki\MagicWordFinder + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class MagicWordFinderTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\MediaWiki\MagicWordFinder', + new MagicWordFinder() + ); + + $parserOutput = $this->getMockBuilder( 'ParserOutput' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\MagicWordFinder', + new MagicWordFinder( $parserOutput ) + ); + } + + /** + * @dataProvider magicWordsProvider + */ + public function testMatchAndRemove( $magicWord, $text, $expectedText, $expectedWords ) { + + $instance = new MagicWordFinder(); + $words = $instance->matchAndRemove( $magicWord, $text ); + + $this->assertInternalType( 'array', $words ); + $this->assertEquals( $expectedWords, $words ); + $this->assertEquals( $expectedText, $text ); + } + + public function testSetGetMagicWords() { + + $this->assertMagicWord( + new MagicWordFinder( new ParserOutput() ), + array( 'Foo' ) + ); + } + + public function testSetGetMagicWordsOnLegacyStorage() { + + $instance = $this->getMockBuilder( '\SMW\MediaWiki\MagicWordFinder' ) + ->disableOriginalConstructor() + ->setMethods( array( 'hasExtensionData' ) ) + ->getMock(); + + $instance->expects( $this->any() ) + ->method( 'hasExtensionData' ) + ->will( $this->returnValue( false ) ); + + $this->assertMagicWord( + $instance->setOutput( new ParserOutput() ), + array( 'Foo' ) + ); + } + + protected function assertMagicWord( $instance, $magicWord ) { + + $this->assertNull( $instance->getMagicWords() ); + + $instance->setMagicWords( $magicWord ); + + $this->assertEquals( + $magicWord, + $instance->getMagicWords() + ); + } + + /** + * @return array + */ + public function magicWordsProvider() { + + $provider = array(); + + $provider[] = array( + 'SMW_NOFACTBOX', + 'Lorem ipsum dolor sit amet consectetuer auctor at quis', + 'Lorem ipsum dolor sit amet consectetuer auctor at quis', + array() + ); + + $provider[] = array( + 'SMW_NOFACTBOX', + 'Lorem ipsum dolor sit __NOFACTBOX__ amet consectetuer auctor at quis', + 'Lorem ipsum dolor sit amet consectetuer auctor at quis', + array( 'SMW_NOFACTBOX' ) + ); + + $provider[] = array( + 'SMW_SHOWFACTBOX', + 'Lorem ipsum dolor __NOFACTBOX__ sit amet consectetuer auctor at quis __SHOWFACTBOX__', + 'Lorem ipsum dolor __NOFACTBOX__ sit amet consectetuer auctor at quis ', + array( 'SMW_SHOWFACTBOX' ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/PageCreatorTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/PageCreatorTest.php new file mode 100644 index 00000000..50d5f8a6 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/PageCreatorTest.php @@ -0,0 +1,51 @@ +<?php + +namespace SMW\Tests\MediaWiki; + +use SMW\MediaWiki\PageCreator; +use SMW\Tests\Util\Mock\MockTitle; + +/** + * @covers \SMW\MediaWiki\PageCreator + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class PageCreatorTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\MediaWiki\PageCreator', + new PageCreator() + ); + } + + public function testCreatePage() { + + $instance = new PageCreator(); + + $this->assertInstanceOf( + '\WikiPage', + $instance->createPage( MockTitle::buildMock( __METHOD__ ) ) + ); + } + + public function testCreateFilePage() { + + $instance = new PageCreator(); + + $this->assertInstanceOf( + '\WikiFilePage', + $instance->createFilePage( MockTitle::buildMock( __METHOD__ ) ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/PageInfoProviderTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/PageInfoProviderTest.php new file mode 100644 index 00000000..c673ac4c --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/PageInfoProviderTest.php @@ -0,0 +1,326 @@ +<?php + +namespace SMW\Tests\MediaWiki; + +use SMW\Tests\Util\Mock\MockTitle; +use SMW\MediaWiki\PageInfoProvider; + +/** + * @covers \SMW\MediaWiki\PageInfoProvider + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class PageInfoProviderTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $wikipage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\PageInfoProvider', + new PageInfoProvider( $wikipage ) + ); + } + + public function testWikiPage_TYPE_MODIFICATION_DATE() { + + $instance = $this->constructPageInfoProviderInstance( + array( + 'wikiPage' => array( 'getTimestamp' => 1272508903 ), + 'revision' => array(), + 'user' => array(), + ) + ); + + $this->assertEquals( 1272508903, $instance->getModificationDate() ); + } + + public function testWikiPage_TYPE_CREATION_DATE() { + + $revision = $this->getMockBuilder( '\Revision' ) + ->disableOriginalConstructor() + ->getMock(); + + $revision->expects( $this->any() ) + ->method( 'getTimestamp' ) + ->will( $this->returnValue( 1272508903 ) ); + + $title = MockTitle::buildMock( 'Lula' ); + + $title->expects( $this->any() ) + ->method( 'getFirstRevision' ) + ->will( $this->returnValue( $revision ) ); + + $instance = $this->constructPageInfoProviderInstance( + array( + 'wikiPage' => array( 'getTitle' => $title ), + 'revision' => array(), + 'user' => array(), + ) + ); + + $this->assertEquals( 1272508903, $instance->getCreationDate() ); + } + + /** + * @dataProvider parentIdProvider + */ + public function testWikiPage_TYPE_NEW_PAGE_ForRevision( $parentId, $expected ) { + + $instance = $this->constructPageInfoProviderInstance( + array( + 'wikiPage' => array(), + 'revision' => array( 'getParentId' => $parentId ), + 'user' => array(), + ) + ); + + $this->assertEquals( $expected, $instance->isNewPage() ); + } + + /** + * @dataProvider parentIdProvider + */ + public function testWikiPage_TYPE_NEW_PAGE( $parentId, $expected ) { + + $revision = $this->getMockBuilder( '\Revision' ) + ->disableOriginalConstructor() + ->getMock(); + + $revision->expects( $this->any() ) + ->method( 'getParentId' ) + ->will( $this->returnValue( $parentId ) ); + + $instance = $this->constructPageInfoProviderInstance( + array( + 'wikiPage' => array( 'getRevision' => $revision ), + 'revision' => array( ), + 'user' => array(), + ) + ); + + $this->assertEquals( $expected, $instance->isNewPage() ); + } + + public function parentIdProvider() { + + $provider = array( + array( 90001, false ), + array( null , true ) + ); + + return $provider; + } + + public function testWikiPage_TYPE_LAST_EDITOR() { + + $userPage = MockTitle::buildMock( 'Lula' ); + + $userPage->expects( $this->any() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( NS_USER ) ); + + $instance = $this->constructPageInfoProviderInstance( + array( + 'wikiPage' => array(), + 'revision' => array(), + 'user' => array( 'getUserPage' => $userPage ), + ) + ); + + $this->assertEquals( $userPage, $instance->getLastEditor() ); + } + + public function constructPageInfoProviderInstance( array $parameters ) { + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + foreach ( $parameters['wikiPage'] as $method => $returnValue ) { + $wikiPage->expects( $this->any() ) + ->method( $method ) + ->will( $this->returnValue( $returnValue ) ); + } + + $revision = $this->getMockBuilder( '\Revision' ) + ->disableOriginalConstructor() + ->getMock(); + + foreach ( $parameters['revision'] as $method => $returnValue ) { + $revision->expects( $this->any() ) + ->method( $method ) + ->will( $this->returnValue( $returnValue ) ); + } + + $user = $this->getMockBuilder( '\User' ) + ->disableOriginalConstructor() + ->getMock(); + + foreach ( $parameters['user'] as $method => $returnValue ) { + $user->expects( $this->any() ) + ->method( $method ) + ->will( $this->returnValue( $returnValue ) ); + } + + return new PageInfoProvider( + $wikiPage, + ( $parameters['revision'] !== array() ? $revision : null ), + ( $parameters['user'] !== array() ? $user : null ) + ); + } + + /** + * @dataProvider uploadStatusWikiFilePageDataProvider + */ + public function testWikiFilePage_TYPE_NEW_PAGE( $uploadStatus, $expected ) { + + $wikiFilePage = $this->getMockBuilder( '\WikiFilePage' ) + ->disableOriginalConstructor() + ->getMock(); + + if ( $uploadStatus !== null ) { + $wikiFilePage->smwFileReUploadStatus = $uploadStatus; + } + + $instance = new PageInfoProvider( $wikiFilePage ); + + $this->assertEquals( $expected, $instance->isNewPage() ); + } + + /** + * @dataProvider mediaTypeWikiFilePageDataProvider + */ + public function testWikiFilePage_MEDIA_TYPE( $file, $expected ) { + + $wikiFilePage = $this->getMockBuilder( '\WikiFilePage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiFilePage->expects( $this->any() ) + ->method( 'isFilePage' ) + ->will( $this->returnValue( true ) ); + + $wikiFilePage->expects( $this->any() ) + ->method( 'getFile' ) + ->will( $this->returnValue( $file ) ); + + $instance = new PageInfoProvider( $wikiFilePage ); + + $this->assertEquals( $expected, $instance->getMediaType() ); + } + + /** + * @dataProvider mimeTypeWikiFilePageDataProvider + */ + public function testWikiFilePage_MIME_TYPE( $file, $expected ) { + + $wikiFilePage = $this->getMockBuilder( '\WikiFilePage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiFilePage->expects( $this->any() ) + ->method( 'isFilePage' ) + ->will( $this->returnValue( true ) ); + + $wikiFilePage->expects( $this->any() ) + ->method( 'getFile' ) + ->will( $this->returnValue( $file ) ); + + $instance = new PageInfoProvider( $wikiFilePage ); + + $this->assertEquals( $expected, $instance->getMimeType() ); + } + + public function testWikiPage_MEDIA_TYPE() { + + $wikiFilePage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new PageInfoProvider( $wikiFilePage ); + + $this->assertEquals( null, $instance->getMediaType() ); + } + + public function testWikiPage_MIME_TYPE() { + + $wikiFilePage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new PageInfoProvider( $wikiFilePage ); + + $this->assertEquals( null, $instance->getMimeType() ); + } + + public function uploadStatusWikiFilePageDataProvider() { + + $provider = array( + array( null, false ), + array( false, true ), + array( true , false ) + ); + + return $provider; + } + + public function mediaTypeWikiFilePageDataProvider() { + + $fileWithMedia = $this->getMockBuilder( '\File' ) + ->disableOriginalConstructor() + ->getMock(); + + $fileWithMedia->expects( $this->any() ) + ->method( 'getMediaType' ) + ->will( $this->returnValue( 'FooMedia' ) ); + + $fileNullMedia = $this->getMockBuilder( '\File' ) + ->disableOriginalConstructor() + ->getMock(); + + $fileNullMedia->expects( $this->any() ) + ->method( 'getMediaType' ) + ->will( $this->returnValue( null ) ); + + $provider[] = array( $fileWithMedia, 'FooMedia' ); + $provider[] = array( $fileNullMedia, null ); + + return $provider; + } + + public function mimeTypeWikiFilePageDataProvider() { + + $fileWithMime = $this->getMockBuilder( '\File' ) + ->disableOriginalConstructor() + ->getMock(); + + $fileWithMime->expects( $this->any() ) + ->method( 'getMimeType' ) + ->will( $this->returnValue( 'FooMime' ) ); + + $fileNullMime = $this->getMockBuilder( '\File' ) + ->disableOriginalConstructor() + ->getMock(); + + $fileNullMime->expects( $this->any() ) + ->method( 'getMediaType' ) + ->will( $this->returnValue( null ) ); + + $provider[] = array( $fileWithMime, 'FooMime' ); + $provider[] = array( $fileNullMime, null ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/RedirectTargetFinderTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/RedirectTargetFinderTest.php new file mode 100644 index 00000000..1353618b --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/RedirectTargetFinderTest.php @@ -0,0 +1,53 @@ +<?php + +namespace SMW\Tests\MediaWiki; + +use SMW\MediaWiki\RedirectTargetFinder; + +use Title; + +/** + * @covers \SMW\MediaWiki\RedirectTargetFinder + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class RedirectTargetFinderTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\MediaWiki\RedirectTargetFinder', + new RedirectTargetFinder() + ); + } + + /** + * @dataProvider redirectTextProvider + */ + public function testFindTargetFromText( $text, $expectedHasTarget, $expectedGetTarget ) { + + $instance = new RedirectTargetFinder(); + $instance->findTarget( $text ); + + $this->assertEquals( $expectedHasTarget, $instance->hasTarget() ); + $this->assertEquals( $expectedGetTarget, $instance->getTarget() ); + } + + public function redirectTextProvider() { + + $provider[] = array( '#REDIRECT [[:Lala]]', true, Title::newFromText( 'Lala' ) ); + $provider[] = array( '#REDIRECT [[Lala]]', true, Title::newFromText( 'Lala' ) ); + $provider[] = array( '[[:Lala]]', false, null ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/TitleCreatorTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/TitleCreatorTest.php new file mode 100644 index 00000000..d53c7b27 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/TitleCreatorTest.php @@ -0,0 +1,114 @@ +<?php + +namespace SMW\Tests\MediaWiki; + +use SMW\MediaWiki\TitleCreator; +use SMW\Tests\Util\Mock\MockTitle; + +/** + * @covers \SMW\MediaWiki\TitleCreator + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class TitleCreatorTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\MediaWiki\TitleCreator', + new TitleCreator() + ); + } + + public function testCreateTitleToNotResolveRedirectTarget() { + + $instance = new TitleCreator(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\TitleCreator', + $instance->createFromText( __METHOD__ ) + ); + + $this->assertInstanceOf( + '\Title', + $instance->createFromText( __METHOD__ )->getTitle() + ); + } + + public function testCreateTitleTryToResolveRedirectOnMissingPageCreatorThrowsException() { + + $instance = new TitleCreator(); + + $this->setExpectedException( 'RuntimeException' ); + $instance->createFromText( __METHOD__ )->findRedirect(); + } + + public function testCreateTitleToResolveRedirectTarget() { + + $instance = $this->createInstanceWithResolvableRedirect(); + + $this->assertInstanceOf( + '\Title', + $instance->createFromText( __METHOD__ )->findRedirect()->getTitle() + ); + } + + public function testCreateTitleWithResolvingRedirectTargetThrowsException() { + + $instance = $this->createInstanceWithUnresolvableRedirect(); + + $this->setExpectedException( 'RuntimeException' ); + $instance->createFromText( __METHOD__ )->findRedirect(); + } + + private function createInstanceWithResolvableRedirect() { + return $this->createInstance( true, true ); + } + + private function createInstanceWithUnresolvableRedirect() { + return $this->createInstance( false, false ); + } + + private function createInstance( $isRedirect, $isValidRedirectTarget ) { + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage->expects( ( $isRedirect ? $this->atLeastOnce() : $this->never() ) ) + ->method( 'getRedirectTarget' ) + ->will( $this->returnValue( MockTitle::buildMock( 'Ooooooo' ) ) ); + + $pageCreator = $this->getMockBuilder( '\SMW\MediaWiki\PageCreator' ) + ->disableOriginalConstructor() + ->getMock(); + + $pageCreator->expects( $this->any() ) + ->method( 'createPage' ) + ->will( $this->returnValue( $wikiPage ) ); + + $instance = $this->getMockBuilder( '\SMW\MediaWiki\TitleCreator' ) + ->setConstructorArgs( array( $pageCreator ) ) + ->setMethods( array( 'isValidRedirectTarget', 'isRedirect' ) ) + ->getMock(); + + $instance->expects( $this->atLeastOnce() ) + ->method( 'isValidRedirectTarget' ) + ->will( $this->returnValue( $isValidRedirectTarget ) ); + + $instance->expects( $this->at( 0 ) ) + ->method( 'isRedirect' ) + ->will( $this->returnValue( $isRedirect ) ); + + return $instance; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/TitleLookupTest.php b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/TitleLookupTest.php new file mode 100644 index 00000000..ac3569ff --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/MediaWiki/TitleLookupTest.php @@ -0,0 +1,223 @@ +<?php + +namespace SMW\Tests\MediaWiki; + +use SMW\MediaWiki\TitleLookup; + +use Title; + +/** + * @covers \SMW\MediaWiki\TitleLookup + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-unit + * @group mediawiki-databaseless + * + * @license GNU GPL v2+ + * @since 1.9.2 + * + * @author mwjames + */ +class TitleLookupTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\MediaWiki\TitleLookup', + new TitleLookup( $database ) + ); + } + + public function testSelectAllOnCategoryNamespace() { + + $row = new \stdClass; + $row->cat_title = 'Foo'; + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->any() ) + ->method( 'select' ) + ->with( $this->stringContains( 'category' ), + $this->anything(), + $this->anything(), + $this->anything(), + $this->anything() ) + ->will( $this->returnValue( array( $row ) ) ); + + $instance = new TitleLookup( $database ); + + $this->assertArrayOfTitles( $instance->byNamespace( NS_CATEGORY )->selectAll() ); + } + + public function testSelectAllOnMainNamespace() { + + $row = new \stdClass; + $row->page_namespace = NS_MAIN; + $row->page_title = 'Bar'; + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->any() ) + ->method( 'select' ) + ->with( $this->anything(), + $this->anything(), + $this->equalTo( array( 'page_namespace' => NS_MAIN ) ), + $this->anything(), + $this->anything() ) + ->will( $this->returnValue( array( $row ) ) ); + + $instance = new TitleLookup( $database ); + + $this->assertArrayOfTitles( $instance->byNamespace( NS_MAIN )->selectAll() ); + } + + public function testSelectByRangeOnCategoryNamespace() { + + $row = new \stdClass; + $row->cat_title = 'Foo'; + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->any() ) + ->method( 'select' ) + ->with( $this->stringContains( 'category' ), + $this->anything(), + $this->equalTo( array( "cat_id BETWEEN 1 AND 5" ) ), + $this->anything(), + $this->anything() ) + ->will( $this->returnValue( array( $row ) ) ); + + $instance = new TitleLookup( $database ); + + $this->assertArrayOfTitles( $instance->byNamespace( NS_CATEGORY )->selectByIdRange( 1, 5 ) ); + } + + public function testSelectByRangeOnMainNamespace() { + + $row = new \stdClass; + $row->page_namespace = NS_MAIN; + $row->page_title = 'Bar'; + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->any() ) + ->method( 'select' ) + ->with( $this->anything(), + $this->anything(), + $this->equalTo( array( "page_id BETWEEN 6 AND 10", 'page_namespace' => NS_MAIN ) ), + $this->anything(), + $this->anything() ) + ->will( $this->returnValue( array( $row ) ) ); + + $instance = new TitleLookup( $database ); + + $this->assertArrayOfTitles( $instance->byNamespace( NS_MAIN )->selectByIdRange( 6, 10 ) ); + } + + public function testSelectAllOnMainNamespaceWithEmptyResult() { + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->any() ) + ->method( 'select' ) + ->with( $this->anything(), + $this->anything(), + $this->equalTo( array( 'page_namespace' => NS_MAIN ) ), + $this->anything(), + $this->anything() ) + ->will( $this->returnValue( false ) ); + + $instance = new TitleLookup( $database ); + + $this->assertArrayOfTitles( $instance->byNamespace( NS_MAIN )->selectAll() ); + } + + public function testSelectMaxIdForMainNamespace() { + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->once() ) + ->method( 'selectField' ) + ->with( $this->equalTo( 'page' ), + $this->anything(), + $this->anything(), + $this->anything() ) + ->will( $this->returnValue( 9999 ) ); + + $instance = new TitleLookup( $database ); + + $this->assertEquals( 9999, $instance->byNamespace( NS_MAIN )->selectMaxId() ); + } + + public function testSelectMaxIdForCategoryNamespace() { + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->once() ) + ->method( 'selectField' ) + ->with( $this->equalTo( 'category' ), + $this->anything(), + $this->anything(), + $this->anything() ) + ->will( $this->returnValue( 1111 ) ); + + $instance = new TitleLookup( $database ); + + $this->assertEquals( 1111, $instance->byNamespace( NS_CATEGORY )->selectMaxId() ); + } + + public function testSelectAllOnMissingNamespaceThrowsException() { + + $this->setExpectedException( 'UnexpectedValueException' ); + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new TitleLookup( $database ); + $instance->selectAll(); + } + + public function testSelectByRangeOnMissingNamespaceThrowsException() { + + $this->setExpectedException( 'UnexpectedValueException' ); + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new TitleLookup( $database ); + $instance->selectByIdRange( 1, 5 ); + } + + protected function assertArrayOfTitles( $arrayOfTitles ) { + + $this->assertInternalType( 'array', $arrayOfTitles ); + + foreach ( $arrayOfTitles as $title ) { + $this->assertInstanceOf( 'Title', $title ); + } + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/NamespaceExaminerTest.php b/SemanticMediaWiki/tests/phpunit/includes/NamespaceExaminerTest.php new file mode 100644 index 00000000..e2b87fea --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/NamespaceExaminerTest.php @@ -0,0 +1,145 @@ +<?php + +namespace SMW\Test; + +use SMW\NamespaceExaminer; +use SMW\Settings; + +/** + * Tests for the NamespaceExaminer class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\NamespaceExaminer + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class NamespaceExaminerTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string + */ + public function getClass() { + return '\SMW\NamespaceExaminer'; + } + + /** + * Helper method that returns a NamespaceExaminer object + * + * @param array $namespaces + * + * @return NamespaceExaminer + */ + private function getInstance( array $namespaces = array() ) { + return new NamespaceExaminer( $namespaces ); + } + + /** + * @test NamespaceExaminer::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $instance = $this->getInstance( array( NS_MAIN => true ) ); + $this->assertInstanceOf( $this->getClass(), $instance ); + } + + /** + * @test NamespaceExaminer::isSemanticEnabled + * + * @since 1.9 + */ + public function testIsSemanticEnabled() { + + $instance = $this->getInstance( array( NS_MAIN => true ) ); + $this->assertTrue( $instance->isSemanticEnabled( NS_MAIN ) ); + + $instance = $this->getInstance( array( NS_MAIN => false ) ); + $this->assertFalse( $instance->isSemanticEnabled( NS_MAIN ) ); + + $instance = $this->getInstance(); + $this->assertFalse( $instance->isSemanticEnabled( NS_MAIN ) ); + + } + + /** + * @test NamespaceExaminer::isSemanticEnabled + * + * @since 1.9 + */ + public function testNoNumberException() { + $this->setExpectedException( '\SMW\InvalidNamespaceException' ); + + $instance = $this->getInstance( array( NS_MAIN => true ) ); + $this->assertTrue( $instance->isSemanticEnabled( 'lula' ) ); + } + + /** + * @test NamespaceExaminer::isSemanticEnabled + * + * Bug 51435; return false instead of an Exception + * + * @since 1.9 + */ + public function testNoValidNamespaceException() { + $instance = $this->getInstance( array( NS_MAIN => true ) ); + $this->assertFalse( $instance->isSemanticEnabled( 99991001 ) ); + } + + /** + * @test NamespaceExaminer::getInstance + * + * @since 1.9 + */ + public function testGetInstance() { + + $instance = NamespaceExaminer::getInstance(); + $this->assertInstanceOf( $this->getClass(), $instance ); + + // Static instance + $this->assertTrue( $instance === NamespaceExaminer::getInstance() ); + + // Reset static instance + NamespaceExaminer::reset(); + $this->assertFalse( $instance === NamespaceExaminer::getInstance() ); + + } + + /** + * @test NamespaceExaminer::newFromArray + * + * @since 1.9 + */ + public function testNewFromArray() { + $instance = NamespaceExaminer::newFromArray( array( NS_MAIN => true ) ); + + $this->assertInstanceOf( $this->getClass(), $instance ); + $this->assertTrue( $instance->isSemanticEnabled( NS_MAIN ) ); + } + + /** + * @see smwfIsSemanticsProcessed + * + * FIXME Delete this test in 1.11 + * + * @since 1.9 + */ + public function testSmwfIsSemanticsProcessed() { + $result = smwfIsSemanticsProcessed( NS_MAIN ); + + $this->assertInternalType( 'boolean', $result ); + $this->assertTrue( $result ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/NamespaceManagerTest.php b/SemanticMediaWiki/tests/phpunit/includes/NamespaceManagerTest.php new file mode 100644 index 00000000..32c42e04 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/NamespaceManagerTest.php @@ -0,0 +1,132 @@ +<?php + +namespace SMW\Test; + +use SMW\NamespaceManager; + +/** + * @covers \SMW\NamespaceManager + * + * @group SMW + * @group SMWExtension + * @group medium + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class NamespaceManagerTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\NamespaceManager'; + } + + /** + * @since 1.9 + * + * @return NamespaceManager + */ + private function newInstance( &$test = array(), $langCode = 'en' ) { + + $default = array( + 'smwgNamespacesWithSemanticLinks' => array(), + 'wgNamespacesWithSubpages' => array(), + 'wgExtraNamespaces' => array(), + 'wgNamespaceAliases' => array(), + 'wgLanguageCode' => $langCode + ); + + $test = array_merge( $default, $test ); + + $smwBasePath = __DIR__ . '../../../..'; + + return new NamespaceManager( $test, $smwBasePath ); + } + + /** + * @since 1.9 + */ + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testExecution() { + + $test = array(); + + $this->newInstance( $test )->run(); + $this->assertNotEmpty( $test ); + + } + + /** + * @since 1.9 + */ + public function testExecutionWithIncompleteConfiguration() { + + $test = array( + 'wgExtraNamespaces' => '', + 'wgNamespaceAliases' => '' + ); + + $this->newInstance( $test )->run(); + $this->assertNotEmpty( $test ); + + } + + /** + * @since 1.9 + */ + public function testExecutionWithLanguageFallback() { + + $test = array(); + + $this->newInstance( $test, 'foo' )->run(); + $this->assertNotEmpty( $test ); + + } + + /** + * @since 1.9 + */ + public function testGetCanonicalNames() { + + $result = NamespaceManager::getCanonicalNames(); + + $this->assertInternalType( 'array', $result ); + $this->assertCount( 6, $result ); + + } + + /** + * @since 1.9 + */ + public function testBuildNamespaceIndex() { + $this->assertInternalType( 'array', NamespaceManager::buildNamespaceIndex( 100 ) ); + } + + /** + * @since 1.9 + */ + public function testInitCustomNamespace() { + + $test = array(); + NamespaceManager::initCustomNamespace( $test ); + + $this->assertNotEmpty( $test ); + $this->assertEquals( + 100, + $test['smwgNamespaceIndex'], + 'Asserts that smwgNamespaceIndex is being set to a default index' + ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/ParserDataTest.php b/SemanticMediaWiki/tests/phpunit/includes/ParserDataTest.php new file mode 100644 index 00000000..1126b617 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/ParserDataTest.php @@ -0,0 +1,239 @@ +<?php + +namespace SMW\Tests; + +use SMW\Tests\Util\SemanticDataValidator; + +use SMW\DataValueFactory; +use SMW\SemanticData; +use SMW\ParserData; +use SMW\DIWikiPage; +use SMW\Application; + +use ParserOutput; +use Title; + +/** + * @covers \SMW\ParserData + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class ParserDataTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $title = $this->getMockBuilder( 'Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $title->expects( $this->once() ) + ->method( 'getNamespace' ) + ->will( $this->returnValue( -1 ) ); + + $parserOutput = $this->getMockBuilder( 'ParserOutput' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\ParserData', + new ParserData( $title, $parserOutput ) + ); + } + + public function testInitialDataIsEmpty() { + + $title = Title::newFromText( __METHOD__ ); + $parserOutput = new ParserOutput(); + + $instance = new ParserData( $title, $parserOutput ); + + $this->assertTrue( $instance->getSemanticData()->isEmpty() ); + } + + public function testUpdateStatus() { + + $title = Title::newFromText( __METHOD__ ); + $parserOutput = new ParserOutput(); + + $instance = new ParserData( $title, $parserOutput ); + $this->assertTrue( $instance->getUpdateStatus() ); + + $instance->disableBackgroundUpdateJobs(); + $this->assertFalse( $instance->getUpdateStatus() ); + } + + public function testGetterInstances() { + + $title = Title::newFromText( __METHOD__ ); + $parserOutput = new ParserOutput(); + + $instance = new ParserData( $title, $parserOutput ); + + $this->assertInstanceOf( 'Title', $instance->getTitle() ); + $this->assertInstanceOf( 'ParserOutput', $instance->getOutput() ); + $this->assertInstanceOf( '\SMW\DIWikiPage', $instance->getSubject() ); + } + + public function testAddDataVlaueAndClear() { + + $title = Title::newFromText( __METHOD__ ); + $parserOutput = new ParserOutput(); + + $instance = new ParserData( $title, $parserOutput ); + + $this->assertTrue( $instance->getSemanticData()->isEmpty() ); + + $instance->addDataValue( + DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Bar' ) + ); + + $this->assertFalse( $instance->getSemanticData()->isEmpty() ); + $instance->clearData(); + + $this->assertTrue( $instance->getSemanticData()->isEmpty() ); + } + + public function testAddDataValueAndUpdateOutput() { + + $title = Title::newFromText( __METHOD__ ); + $parserOutput = new ParserOutput(); + + $instance = new ParserData( $title, $parserOutput ); + + $instance->addDataValue( + DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Bar' ) + ); + + $this->assertFalse( $instance->getSemanticData()->isEmpty() ); + $instance->updateOutput(); + + $title = Title::newFromText( __METHOD__ .'-1' ); + + $newInstance = new ParserData( $title, $instance->getOutput() ); + + $this->assertTrue( + $instance->getSemanticData()->getHash() === $newInstance->getSemanticData()->getHash(), + 'Asserts that updateOutput() yielded an update, resulting with an identical hash in both containers' + ); + } + + public function testSetGetSemanticData() { + + $title = Title::newFromText( __METHOD__ ); + $parserOutput = new ParserOutput(); + + $instance = new ParserData( $title, $parserOutput ); + + $this->assertTrue( $instance->getSemanticData()->isEmpty() ); + + $semanticData = new SemanticData( DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ) ); + + $semanticData->addDataValue( + DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Bar' ) + ); + + $instance->setSemanticData( $semanticData ); + + $this->assertFalse( $instance->getSemanticData()->isEmpty() ); + + $this->assertTrue( + $semanticData->getHash() === $instance->getSemanticData()->getHash() + ); + } + + public function getPropertyValueDataProvider() { + return array( + array( 'Foo' , 'Bar', 0, 1 ), + array( '-Foo' , 'Bar', 1, 0 ), + array( '_Foo' , 'Bar', 1, 0 ), + ); + } + + /** + * @dataProvider getPropertyValueDataProvider + */ + public function testAddDataValue( $propertyName, $value, $errorCount, $propertyCount ) { + + $title = Title::newFromText( __METHOD__ ); + $parserOutput = new ParserOutput(); + + $instance = new ParserData( $title, $parserOutput ); + + $instance->addDataValue( + DataValueFactory::getInstance()->newPropertyValue( + $propertyName, + $value + ) + ); + + if ( $errorCount > 0 ) { + return $this->assertCount( $errorCount, $instance->getErrors() ); + } + + $expected = array( + 'propertyCount' => $propertyCount, + 'propertyLabels' => $propertyName, + 'propertyValues' => $value + ); + + $semanticDataValidator = new SemanticDataValidator(); + + $semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance->getSemanticData() + ); + } + + public function testSetGetForNonExtensionDataLegacyAccess() { + + $title = Title::newFromText( __METHOD__ ); + $parserOutput = new ParserOutput(); + + $instance = $this->getMockBuilder( '\SMW\ParserData' ) + ->setConstructorArgs( array( $title, $parserOutput ) ) + ->setMethods( array( 'hasExtensionData' ) ) + ->getMock(); + + $instance->expects( $this->any() ) + ->method( 'hasExtensionData' ) + ->will( $this->returnValue( false ) ); + + $instance->updateOutput(); + + $this->assertInstanceOf( + '\SMW\SemanticData', + $instance->getSemanticData() + ); + } + + public function testUpdateStore() { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( 'updateData' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->once() ) + ->method( 'updateData' ); + + Application::getInstance()->registerObject( 'Store', $store ); + + $instance = new ParserData( + Title::newFromText( __METHOD__ ), + new ParserOutput() + ); + + $this->assertTrue( $instance->updateStore() ); + + Application::clear(); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/ProfilerTest.php b/SemanticMediaWiki/tests/phpunit/includes/ProfilerTest.php new file mode 100644 index 00000000..89f42abf --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/ProfilerTest.php @@ -0,0 +1,100 @@ +<?php + +namespace SMW\Test; + +use SMW\Profiler; + +use ReflectionClass; + +/** + * Tests for the Profiler class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\Profiler + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class ProfilerTest extends SemanticMediaWikiTestCase { + + /** + * Holds original values of MediaWiki configuration settings + * @var array + */ + private $mwGlobals = array(); + + /** Set-up */ + protected function setUp() { + parent::setUp(); + + $this->mwGlobals['wgProfiler'] = $GLOBALS['wgProfiler']; + $GLOBALS['wgProfiler']['class'] = '\ProfilerStub'; + } + + /** Tear down */ + protected function tearDown() { + $GLOBALS['wgProfiler'] = $this->mwGlobals['wgProfiler']; + $this->mwGlobals = array(); + + parent::tearDown(); + } + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\Profiler'; + } + + /** + * @test Profiler::getInstance + * @test Profiler::reset + * + * @since 1.9 + */ + public function testGetInstance() { + + // Never mind the unset here because setup/tearDown + // stores the original setting + unset( $GLOBALS['wgProfiler'] ); + + $this->assertEquals( null, Profiler::getInstance() ); + + $GLOBALS['wgProfiler']['class'] = '\ProfilerStub'; + + Profiler::reset(); + $instance = Profiler::getInstance(); + + $this->assertInstanceOf( '\ProfilerStub', $instance ); + $this->assertTrue( $instance === Profiler::getInstance(), 'Failed asserting that the instance is identical' ); + + } + + /** + * @test Profiler::In + * @test Profiler::Out + * + * @since 1.9 + */ + public function testInOut() { + + Profiler::reset(); + + $this->assertInstanceOf( '\ProfilerStub', Profiler::In( 'Lala' ) ); + $this->assertInstanceOf( '\ProfilerStub', Profiler::Out( 'Lala' ) ); + $this->assertInstanceOf( '\ProfilerStub', Profiler::In( 'Lila', true ) ); + $this->assertInstanceOf( '\ProfilerStub', Profiler::Out( 'Lila', true ) ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/PropertyTypeDiffFinderTest.php b/SemanticMediaWiki/tests/phpunit/includes/PropertyTypeDiffFinderTest.php new file mode 100644 index 00000000..ca7dde09 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/PropertyTypeDiffFinderTest.php @@ -0,0 +1,180 @@ +<?php + +namespace SMW\Tests; + +use SMW\PropertyTypeDiffFinder; +use SMW\DIProperty; +use SMW\DIWikiPage; +use SMW\Settings; +use SMW\Application; + +use Title; + +/** + * @covers \SMW\PropertyTypeDiffFinder + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class PropertyTypeDiffFinderTest extends \PHPUnit_Framework_TestCase { + + /** @var DIWikiPage[] */ + protected $storeValues; + + private $application; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + + $settings = Settings::newFromArray( array( + 'smwgDeclarationProperties' => array( '_PVAL' ), + 'smwgCacheType' => 'hash', + 'smwgEnableUpdateJobs' => false + ) ); + + $this->application->registerObject( 'Settings', $settings ); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $store = $this->getMockBuilder( 'SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\PropertyTypeDiffFinder', + new PropertyTypeDiffFinder( $store, $semanticData ) + ); + } + + /** + * @dataProvider dataItemDataProvider + */ + public function testDetectChanges( $storeValues, $dataValues, $settings, $expected ) { + + $this->storeValues = $storeValues; + + $subject = DIWikiPage::newFromTitle( Title::newFromText( __METHOD__, SMW_NS_PROPERTY ) ); + + $settings = Settings::newFromArray( array( + 'smwgDeclarationProperties' => $settings + ) ); + + $this->application->registerObject( 'Settings', $settings ); + + $updateDispatcherJob = $this->getMockBuilder( 'SMW\MediaWiki\Jobs\UpdateDispatcherJob' ) + ->disableOriginalConstructor() + ->getMock(); + + $expectedToRun = $expected['job'] ? $this->once() : $this->never(); + + $updateDispatcherJob->expects( $expectedToRun ) + ->method( 'run' ) + ->will( $this->returnValue( $subject ) ); + + $jobFactory = $this->getMockBuilder( 'SMW\MediaWiki\Jobs\JobFactory' ) + ->disableOriginalConstructor() + ->getMock(); + + $jobFactory->expects( $this->any() ) + ->method( 'newUpdateDispatcherJob' ) + ->will( $this->returnValue( $updateDispatcherJob ) ); + + $this->application->registerObject( 'JobFactory', $jobFactory ); + + $store = $this->getMockBuilder( 'SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( + 'getPropertyValues' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->atLeastOnce() ) + ->method( 'getPropertyValues' ) + ->will( $this->returnCallback( array( $this, 'mockStorePropertyValuesCallback' ) ) ); + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $semanticData->expects( $this->atLeastOnce() ) + ->method( 'getSubject' ) + ->will( $this->returnValue( $subject ) ); + + $semanticData->expects( $this->atLeastOnce() ) + ->method( 'getPropertyValues' ) + ->will( $this->returnValue( $dataValues ) ); + + $instance = new PropertyTypeDiffFinder( $store, $semanticData ); + $instance->findDiff(); + + $this->assertEquals( + $subject->getTitle(), + $instance->getTitle() + ); + + $this->assertEquals( + $expected['diff'], + $instance->hasDiff() + ); + } + + public function dataItemDataProvider() { + + // Single + $subject = array( + DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ) + ); + + // Multiple + $subjects = array( + DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ . 'm-0' ) ), + DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ . 'm-1' ) ), + DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ . 'm-2' ) ) + ); + + return array( + // $storeValues, $dataValues, $settings, $expected + array( $subjects, array(), array( '_PVAL', '_LIST' ), array( 'diff' => true, 'job' => true ) ), + array( array(), $subjects, array( '_PVAL', '_LIST' ), array( 'diff' => true, 'job' => true ) ), + array( $subject, $subjects, array( '_PVAL', '_LIST' ), array( 'diff' => true, 'job' => true ) ), + array( $subject, array(), array( '_PVAL', '_LIST' ), array( 'diff' => true, 'job' => true ) ), + array( $subject, array(), array( '_PVAL' ), array( 'diff' => true, 'job' => true ) ), + array( $subjects, $subjects, array( '_PVAL' ), array( 'diff' => false, 'job' => false ) ), + array( $subject, $subject, array( '_PVAL' ), array( 'diff' => false, 'job' => false ) ), + array( $subjects, $subjects, array( '_PVAL', '_LIST' ), array( 'diff' => true, 'job' => true ) ), + array( $subject, $subject, array( '_PVAL', '_LIST' ), array( 'diff' => true, 'job' => true ) ) + ); + } + + /** + * Returns an array of SMWDataItem and simulates an alternating + * existencance of return values ('_LIST') + * + * @see Store::getPropertyValues + * + * @return SMWDataItem[] + */ + public function mockStorePropertyValuesCallback( $subject, DIProperty $property, $requestoptions = null ) { + return $property->getKey() === '_LIST' ? array() : $this->storeValues; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/RecurringEventsTest.php b/SemanticMediaWiki/tests/phpunit/includes/RecurringEventsTest.php new file mode 100644 index 00000000..a51adb8e --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/RecurringEventsTest.php @@ -0,0 +1,392 @@ +<?php + +namespace SMW\Test; + +use SMW\RecurringEvents; +use SMW\ParserParameterFormatter; + +/** + * @covers \SMW\RecurringEvents + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group medium + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class RecurringEventsTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\RecurringEvents'; + } + + /** + * @since 1.9 + * + * @return RecurringEvents + */ + private function newInstance( array $params ) { + + $parameters = new ParserParameterFormatter( $params ); + + $settings = $this->newSettings( array( + 'smwgDefaultNumRecurringEvents' => 10, + 'smwgMaxNumRecurringEvents' => 50 + ) ); + + return new RecurringEvents( $parameters->toArray(), $settings ); + } + + /** + * @dataProvider getParametersDataProvider + * + * @since 1.9 + */ + public function testConstructor( array $params ) { + $this->assertInstanceOf( $this->getClass(), $this->newInstance( $params ) ); + } + + /** + * @dataProvider getParametersDataProvider + * + * @since 1.9 + */ + public function testGetErrors( array $params, array $expected ) { + $this->assertCount( $expected['errors'], $this->newInstance( $params )->getErrors() ); + } + + /** + * @dataProvider getParametersDataProvider + * + * @since 1.9 + */ + public function testGetProperty( array $params, array $expected ) { + $this->assertEquals( $expected['property'], $this->newInstance( $params )->getProperty() ); + } + + /** + * @dataProvider getParametersDataProvider + * + * @since 1.9 + */ + public function testGetParameters( array $params, array $expected ) { + $this->assertEquals( $expected['parameters'], $this->newInstance( $params )->getParameters() ); + } + + /** + * @dataProvider getParametersDataProvider + * + * @since 1.9 + */ + public function testGetDates( array $params, array $expected ) { + $this->assertEquals( $expected['dates'], $this->newInstance( $params )->getDates() ); + } + + /** + * @return array + */ + public function getMassInsertDataProvider() { + return array( + array( + array( + 'property=Has birthday', + 'start=01 Feb 1970', + 'Has title=Birthday', + 'unit=month', 'period=12', + 'limit=500', + ), + array( + 'errors' => 0, + 'count' => 501, + 'property' => '', + 'parameters' => array() + ) + ) + ); + } + + /** + * @dataProvider getMassInsertDataProvider + * + * @since 1. + */ + public function testMassInsert( array $params, array $expected ) { + $this->assertCount( $expected['count'], $this->newInstance( $params )->getDates() ); + } + + /** + * @test RecurringEvents::getJulianDay + * + * @since 1.9 + */ + public function testGetJulianDay() { + $instance = $this->newInstance( array() ); + + // SMWDIWikiPage stub object + $dataValue = $this->getMockBuilder( 'SMWTimeValue' ) + ->disableOriginalConstructor() + ->getMock(); + + $dataValue->expects( $this->any() ) + ->method( 'getDataItem' ) + ->will( $this->returnValue( null ) ); + + $this->assertEquals( null, $instance->getJulianDay( $dataValue ) ); + } + + /** + * @return array + */ + public function getParametersDataProvider() { + return array( + // {{#set_recurring_event:property=Has birthday + // |start=01 Feb 1970 + // |has title= Birthday + // |unit=year + // |period=12 + // |limit=3 + // }} + array( + array( + 'property=Has birthday', + 'start=01 Feb 1970', + 'has title=Birthday', + 'unit=month', + 'period=12', + 'limit=3' + ), + array( + 'errors' => 0, + 'dates' => array( '1 February 1970', '1 February 1971 00:00:00', '1 February 1972 00:00:00', '1 February 1973 00:00:00' ), + 'property' => 'Has birthday', + 'parameters' => array( 'has title' => array( 'Birthday' ) ) + ) + ), + + // {{#set_recurring_event:property=Has birthday + // |start=01 Feb 1970 + // |end=01 Feb 1972 + // |has title= Birthday + // |unit=year + // |period=12 + // |limit=3 + // }} + array( + array( + 'property=Has birthday', + 'start=01 Feb 1970', + 'end=01 Feb 1972', + 'has title=Birthday', + 'unit=month', + 'period=12', + 'limit=3' + ), + array( + 'errors' => 0, + 'dates' => array( '1 February 1970', '1 February 1971 00:00:00', '1 February 1972 00:00:00' ), + 'property' => 'Has birthday', + 'parameters' => array( 'has title' => array( 'Birthday' ) ) + ) + ), + + // {{#set_recurring_event:property=Has birthday + // |start=01 Feb 1970 + // |end=01 Feb 1972 + // |has title= Birthday + // |unit=year + // |week number=2 + // |period=12 + // |limit=3 + // }} + array( + array( + 'property=Has birthday', + 'start=01 Feb 1970', + 'end=01 Feb 1972', + 'has title=Birthday', + 'unit=month', + 'week number=2', + 'period=12', + 'limit=3' + ), + array( + 'errors' => 0, + 'dates' => array( '1 February 1970', '14 February 1971 00:00:00' ), + 'property' => 'Has birthday', + 'parameters' => array( 'has title' => array( 'Birthday' ) ) + ) + ), + + // {{#set_recurring_event:property=Has birthday + // |start=01 Feb 1972 02:00 + // |has title=Test 12 + // |unit=week + // |period=4 + // |limit=3 + // }} + array( + array( + 'property=Has birthday', + 'start=01 Feb 1972 02:00', + 'has title=Test 2', + 'unit=week', + 'period=4', + 'limit=3' + ), + array( + 'errors' => 0, + 'dates' => array( '1 February 1972 02:00:00', '29 February 1972 02:00:00', '28 March 1972 02:00:00', '25 April 1972 02:00:00' ), + 'property' => 'Has birthday', + 'parameters' => array( 'has title' => array( 'Test 2' ) ) + ) + ), + + // {{#set_recurring_event:property=Has date + // |start=January 4, 2010 + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010 + // |exclude=January 18, 2010;January 25, 2010 + // }} + array( + array( + 'property=Has date', + 'start=January 4, 2010', + 'unit=week', + 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + 'exclude=January 18, 2010;January 25, 2010' + ), + array( + 'errors' => 0, + 'dates' => array( '4 January 2010', '11 January 2010 00:00:00', '1 February 2010 00:00:00', 'March 16, 2010', 'March 23, 2010' ), + 'property' => 'Has date', + 'parameters' => array() + ) + ), + + // {{#set_recurring_event:property=Has date + // |start=January 4, 2010 + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010|+sep=; + // |exclude=January 18, 2010;January 25, 2010|+sep=; + // }} + array( + array( + 'property=Has date', + 'start=January 4, 2010', + 'unit=week', + 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + '+sep=;', + 'exclude=January 18, 2010;January 25, 2010', + '+sep=;' + ), + array( + 'errors' => 0, + 'dates' => array( '4 January 2010', '11 January 2010 00:00:00', '1 February 2010 00:00:00', 'March 16, 2010', 'March 23, 2010' ), + 'property' => 'Has date', + 'parameters' => array() + ) + ), + + // Simulate start date has wrong type + + // {{#set_recurring_event:property=Has date + // |start=??? + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010 + // |exclude=January 18, 2010;January 25, 2010 + // }} + array( + array( + 'property=Has date', + 'start=???', + 'unit=week', + 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + 'exclude=January 18, 2010;January 25, 2010' + ), + array( + 'errors' => 1, + 'dates' => array(), + 'property' => 'Has date', + 'parameters' => array() + ) + ), + + // Simulate missing start date + + // {{#set_recurring_event:property=Has date + // |start= + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010 + // |exclude=January 18, 2010;January 25, 2010 + // }} + array( + array( + 'property=Has date', + 'start=', + 'unit=week', + 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + 'exclude=January 18, 2010;January 25, 2010' + ), + array( + 'errors' => 1, + 'dates' => array(), + 'property' => 'Has date', + 'parameters' => array() + ) + ), + + // Simulate missing property + + // {{#set_recurring_event:property= + // |start=January 4, 2010 + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010|+sep=; + // |exclude=January 18, 2010;January 25, 2010|+sep=; + // }} + array( + array( + 'property=', + 'start=January 4, 2010', + 'unit=week', 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + '+sep=;', + 'exclude=January 18, 2010;January 25, 2010', + '+sep=;' + ), + array( + 'errors' => 1, + 'dates' => array(), + 'property' => '', + 'parameters' => array() + ) + ), + ); + } +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/Reporter/MessageReporterTestCase.php b/SemanticMediaWiki/tests/phpunit/includes/Reporter/MessageReporterTestCase.php new file mode 100644 index 00000000..0cdfd82f --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Reporter/MessageReporterTestCase.php @@ -0,0 +1,69 @@ +<?php + +namespace SMW\Tests\Reporter; + +/** + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +abstract class MessageReporterTestCase extends \PHPUnit_Framework_TestCase { + + /** + * @return MessageReporter[] + */ + public abstract function getInstances(); + + /** + * Message provider, includes edge cases and random tests + * + * @return array + */ + public function reportMessageProvider() { + $messages = array(); + + $messages[] = ''; + $messages[] = ' '; + + foreach ( array_merge( range( 1, 100 ), array( 1000, 10000 ) ) as $length ) { + $string = array(); + + for ( $position = 0; $position < $length; $position++ ) { + $string[] = chr( mt_rand( 32, 126 ) ); + } + + $messages[] = implode( '', $string ); + } + + return $this->arrayWrap( $messages ); + } + + /** + * @dataProvider reportMessageProvider + * + * @param string $message + */ + public function testReportMessage( $message ) { + foreach ( $this->getInstances() as $reporter ) { + $reporter->reportMessage( $message ); + $reporter->reportMessage( $message ); + $this->assertTrue( true ); + } + } + + protected function arrayWrap( array $elements ) { + return array_map( + function ( $element ) { + return array( $element ); + }, + $elements + ); + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/Reporter/ObservableMessageReporterTest.php b/SemanticMediaWiki/tests/phpunit/includes/Reporter/ObservableMessageReporterTest.php new file mode 100644 index 00000000..ef4d89f4 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Reporter/ObservableMessageReporterTest.php @@ -0,0 +1,115 @@ +<?php + +namespace SMW\Tests\Reporter; + +use SMW\Reporter\ObservableMessageReporter; +use SMW\Reporter\MessageReporter; + +/** + * @covers \SMW\Reporter\ObservableMessageReporter + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class ObservableMessageReporterTest extends MessageReporterTestCase { + + /** + * @return MessageReporter[] + */ + public function getInstances() { + $instances = array(); + + $instances[] = new ObservableMessageReporter(); + + $reporter = new ObservableMessageReporter(); + $reporter->registerMessageReporter( new ObservableMessageReporter() ); + $callback0 = function( $string ) {}; + $callback1 = function( $string ) {}; + $instances[] = $reporter; + + $reporter = clone $reporter; + $reporter->registerReporterCallback( $callback0 ); + $reporter->registerReporterCallback( $callback1 ); + $instances[] = $reporter; + + return $instances; + } + + /** + * @dataProvider reportMessageProvider + * + * @param string $message + */ + public function testCallbackInvocation( $message ) { + $callCount = 0; + $asserter = array( $this, 'assertEquals' ); + + $callback0 = function( $actual ) use ( $message, &$callCount, $asserter ) { + $callCount += 1; + call_user_func( $asserter, $message, $actual ); + }; + + $callback1 = function( $actual ) use ( $message, &$callCount, $asserter ) { + $callCount += 1; + call_user_func( $asserter, $message, $actual ); + }; + + $reporter = new ObservableMessageReporter(); + $reporter->registerReporterCallback( $callback0 ); + $reporter->registerReporterCallback( $callback1 ); + + $reporter->reportMessage( $message ); + + $this->assertEquals( 2, $callCount ); + + $reporter->reportMessage( $message ); + + $this->assertEquals( 4, $callCount ); + } + + /** + * @dataProvider reportMessageProvider + * + * @param string $message + */ + public function testReporterInvocation( $message ) { + $callCount = 0; + $asserter = array( $this, 'assertEquals' ); + + $callback0 = function( $actual ) use ( $message, &$callCount, $asserter ) { + $callCount += 1; + call_user_func( $asserter, $message, $actual ); + }; + + $callback1 = function( $actual ) use ( $message, &$callCount, $asserter ) { + $callCount += 1; + call_user_func( $asserter, $message, $actual ); + }; + + $reporter0 = new ObservableMessageReporter(); + $reporter0->registerReporterCallback( $callback0 ); + + $reporter1 = new ObservableMessageReporter(); + $reporter1->registerReporterCallback( $callback1 ); + + $reporter = new ObservableMessageReporter(); + $reporter->registerMessageReporter( $reporter0 ); + $reporter->registerMessageReporter( $reporter1 ); + + $reporter->reportMessage( $message ); + + $this->assertEquals( 2, $callCount ); + + $reporter->reportMessage( $message ); + + $this->assertEquals( 4, $callCount ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/BadHttpDatabaseResponseExceptionTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/BadHttpDatabaseResponseExceptionTest.php new file mode 100644 index 00000000..5f0e6e6c --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/BadHttpDatabaseResponseExceptionTest.php @@ -0,0 +1,53 @@ +<?php + +namespace SMW\Tests\SPARQLStore; + +use SMW\SPARQLStore\BadHttpDatabaseResponseException; + +/** + * @covers \SMW\SPARQLStore\BadHttpDatabaseResponseException + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class BadHttpDatabaseResponseExceptionTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\SPARQLStore\BadHttpDatabaseResponseException', + new BadHttpDatabaseResponseException( 'Foo', 'Bar', 'Que' ) + ); + } + + /** + * @dataProvider errorCodeProvider + */ + public function testErrorCodes( $errorCode ) { + + $instance = new BadHttpDatabaseResponseException( $errorCode, '', '' ); + $this->assertEquals( $errorCode, $instance->getCode() ); + } + + public function errorCodeProvider() { + + $provider = array( + array( BadHttpDatabaseResponseException::ERROR_MALFORMED ), + array( BadHttpDatabaseResponseException::ERROR_REFUSED ), + array( BadHttpDatabaseResponseException::ERROR_GRAPH_NOEXISTS ), + array( BadHttpDatabaseResponseException::ERROR_GRAPH_EXISTS ), + array( BadHttpDatabaseResponseException::ERROR_OTHER ), + array( BadHttpDatabaseResponseException::ERROR_NOSERVICE ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/BadHttpResponseMapperTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/BadHttpResponseMapperTest.php new file mode 100644 index 00000000..c3f29859 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/BadHttpResponseMapperTest.php @@ -0,0 +1,132 @@ +<?php + +namespace SMW\Tests\SPARQLStore; + +use SMW\SPARQLStore\BadHttpResponseMapper; + +/** + * @covers \SMW\SPARQLStore\BadHttpResponseMapper + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class BadHttpResponseMapperTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $httpRequest = $this->getMockBuilder( '\SMW\HttpRequest' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\BadHttpResponseMapper', + new BadHttpResponseMapper( $httpRequest ) + ); + } + + /** + * @dataProvider curlErrorCodeThatNotThrowsExceptionProvider + */ + public function testResponseToHttpRequestThatNotThrowsException( $curlErrorCode ) { + + $httpRequest = $this->getMockBuilder( '\SMW\HttpRequest' ) + ->disableOriginalConstructor() + ->getMock(); + + $httpRequest->expects( $this->once() ) + ->method( 'getLastErrorCode' ) + ->will( $this->returnValue( $curlErrorCode ) ); + + $instance = new BadHttpResponseMapper( $httpRequest ); + $instance->mapResponseToHttpRequest( 'Foo', 'Bar' ); + } + + public function testResponseToHttpRequestForInvalidErrorCodeThrowsException() { + + $httpRequest = $this->getMockBuilder( '\SMW\HttpRequest' ) + ->disableOriginalConstructor() + ->getMock(); + + $httpRequest->expects( $this->once() ) + ->method( 'getLastErrorCode' ) + ->will( $this->returnValue( 99999 ) ); + + $instance = new BadHttpResponseMapper( $httpRequest ); + + $this->setExpectedException( '\Exception' ); + $instance->mapResponseToHttpRequest( 'Foo', 'Bar' ); + } + + /** + * @dataProvider httpCodeThatThrowsExceptionProvider + */ + public function testResponseToHttpRequesForHttpErrorThatThrowsException( $httpErrorCode ) { + + // PHP doesn't know CURLE_HTTP_RETURNED_ERROR therefore using 22 + // http://curl.haxx.se/libcurl/c/libcurl-errors.html + + $httpRequest = $this->getMockBuilder( '\SMW\HttpRequest' ) + ->disableOriginalConstructor() + ->getMock(); + + $httpRequest->expects( $this->once() ) + ->method( 'getLastErrorCode' ) + ->will( $this->returnValue( 22 ) ); + + $httpRequest->expects( $this->once() ) + ->method( 'getInfo' ) + ->with( $this->equalTo( CURLINFO_HTTP_CODE ) ) + ->will( $this->returnValue( $httpErrorCode ) ); + + $instance = new BadHttpResponseMapper( $httpRequest ); + + $this->setExpectedException( '\SMW\SPARQLStore\BadHttpDatabaseResponseException' ); + $instance->mapResponseToHttpRequest( 'Foo', 'Bar' ); + } + + public function testResponseToHttpRequesForHttpErrorThatNotThrowsException() { + + $httpRequest = $this->getMockBuilder( '\SMW\HttpRequest' ) + ->disableOriginalConstructor() + ->getMock(); + + $httpRequest->expects( $this->once() ) + ->method( 'getLastErrorCode' ) + ->will( $this->returnValue( 22 ) ); + + $httpRequest->expects( $this->once() ) + ->method( 'getInfo' ) + ->with( $this->equalTo( CURLINFO_HTTP_CODE ) ) + ->will( $this->returnValue( 404 ) ); + + $instance = new BadHttpResponseMapper( $httpRequest ); + $instance->mapResponseToHttpRequest( 'Foo', 'Bar' ); + } + + public function curlErrorCodeThatNotThrowsExceptionProvider() { + + $provider = array( + array( CURLE_GOT_NOTHING ), + array( CURLE_COULDNT_CONNECT ) + ); + + return $provider; + } + + public function httpCodeThatThrowsExceptionProvider() { + + $provider = array( + array( 400 ), + array( 500 ) + ); + + return $provider; + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/DatabaseConnectorExceptionTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/DatabaseConnectorExceptionTest.php new file mode 100644 index 00000000..f739df55 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/DatabaseConnectorExceptionTest.php @@ -0,0 +1,126 @@ +<?php + +namespace SMW\Tests\SPARQLStore; + +/** + * @covers \SMW\SPARQLStore\FusekiHttpDatabaseConnector + * @covers \SMW\SPARQLStore\FourstoreHttpDatabaseConnector + * @covers \SMW\SPARQLStore\VirtuosoHttpDatabaseConnector + * @covers \SMW\SPARQLStore\GenericHttpDatabaseConnector + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class DatabaseConnectorExceptionTest extends \PHPUnit_Framework_TestCase { + + private $defaultGraph; + + private $databaseConnectors = array( + '\SMW\SPARQLStore\GenericHttpDatabaseConnector', + '\SMW\SPARQLStore\FusekiHttpDatabaseConnector', + '\SMW\SPARQLStore\FourstoreHttpDatabaseConnector', + '\SMW\SPARQLStore\VirtuosoHttpDatabaseConnector', + + // Legacy and should be removed once obsolete + 'SMWSparqlDatabase4Store', + 'SMWSparqlDatabaseVirtuoso', + 'SMWSparqlDatabase' + ); + + protected function setUp() { + parent::setUp(); + + $this->defaultGraph = 'http://foo/myDefaultGraph'; + } + + /** + * @dataProvider httpDatabaseConnectorInstanceNameProvider + */ + public function testCanConstruct( $httpConnector ) { + + $this->assertInstanceOf( + '\SMW\SPARQLStore\GenericHttpDatabaseConnector', + new $httpConnector( $this->defaultGraph, '' ) + ); + } + + /** + * @dataProvider httpDatabaseConnectorInstanceNameProvider + */ + public function testDoQueryForEmptyQueryEndpointThrowsException( $httpConnector ) { + + $instance = new $httpConnector( + $this->defaultGraph, + '' + ); + + $this->setExpectedException( '\SMW\SPARQLStore\BadHttpDatabaseResponseException' ); + $instance->doQuery( '' ); + } + + /** + * @dataProvider httpDatabaseConnectorInstanceNameProvider + */ + public function testDoUpdateForEmptyUpdateEndpointThrowsException( $httpConnector ) { + + $instance = new $httpConnector( + $this->defaultGraph, + '', + '' + ); + + $this->setExpectedException( '\SMW\SPARQLStore\BadHttpDatabaseResponseException' ); + $instance->doUpdate( '' ); + } + + /** + * @dataProvider httpDatabaseConnectorInstanceNameProvider + */ + public function testDoHttpPostForEmptyDataEndpointThrowsException( $httpConnector ) { + + $instance = new $httpConnector( + $this->defaultGraph, + '', + '', + '' + ); + + $this->setExpectedException( '\SMW\SPARQLStore\BadHttpDatabaseResponseException' ); + $instance->doHttpPost( '' ); + } + + /** + * @dataProvider httpDatabaseConnectorInstanceNameProvider + */ + public function testDoHttpPostForUnreachableDataEndpointThrowsException( $httpConnector ) { + + $instance = new $httpConnector( + $this->defaultGraph, + '', + '', + 'unreachableDataEndpoint' + ); + + $this->setExpectedException( 'Exception' ); + $instance->doHttpPost( '' ); + } + + public function httpDatabaseConnectorInstanceNameProvider() { + + $provider = array(); + + foreach ( $this->databaseConnectors as $databaseConnector ) { + $provider[] = array( $databaseConnector ); + } + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/DatabaseConnectorHttpRequestIntegrityTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/DatabaseConnectorHttpRequestIntegrityTest.php new file mode 100644 index 00000000..183d3eb6 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/DatabaseConnectorHttpRequestIntegrityTest.php @@ -0,0 +1,199 @@ +<?php + +namespace SMW\Tests\SPARQLStore; + +use SMW\Tests\Util\FakeRawResultProvider; + +/** + * @covers \SMW\SPARQLStore\FusekiHttpDatabaseConnector + * @covers \SMW\SPARQLStore\FourstoreHttpDatabaseConnector + * @covers \SMW\SPARQLStore\VirtuosoHttpDatabaseConnector + * @covers \SMW\SPARQLStore\GenericHttpDatabaseConnector + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-sparql + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class DatabaseConnectorHttpRequestIntegrityTest extends \PHPUnit_Framework_TestCase { + + private $databaseConnectors = array( + '\SMW\SPARQLStore\GenericHttpDatabaseConnector', + '\SMW\SPARQLStore\FusekiHttpDatabaseConnector', + '\SMW\SPARQLStore\FourstoreHttpDatabaseConnector', + '\SMW\SPARQLStore\VirtuosoHttpDatabaseConnector', + + // Legacy and should be removed once obsolete + 'SMWSparqlDatabase4Store', + 'SMWSparqlDatabaseVirtuoso', + 'SMWSparqlDatabase' + ); + + /** + * @dataProvider httpDatabaseConnectorInstanceNameForAskProvider + * + * @see https://www.w3.org/TR/rdf-sparql-query/#ask + */ + public function testAskToQueryEndpointOnMockedHttpRequest( $httpDatabaseConnector, $expectedPostField ) { + + $rawResultProvider = new FakeRawResultProvider(); + + $httpRequest = $this->getMockBuilder( '\SMW\HttpRequest' ) + ->disableOriginalConstructor() + ->getMock(); + + $httpRequest->expects( $this->at( 3 ) ) + ->method( 'setOption' ) + ->with( + $this->equalTo( CURLOPT_POSTFIELDS ), + $this->stringContains( $expectedPostField ) ) + ->will( $this->returnValue( true ) ); + + $httpRequest->expects( $this->once() ) + ->method( 'execute' ) + ->will( $this->returnValue( $rawResultProvider->getEmptySparqlResultXml() ) ); + + $instance = new $httpDatabaseConnector( + 'http://foo/myDefaultGraph', + 'http://localhost:9999/query' + ); + + $instance->setHttpRequest( $httpRequest ); + + $federateResultList = $instance->ask( + '?x foaf:name "Foo"', + array( 'foaf' => 'http://xmlns.com/foaf/0.1/>' ) + ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\FederateResultList', + $federateResultList + ); + } + + /** + * @dataProvider httpDatabaseConnectorInstanceNameForDeleteProvider + * + * @see http://www.w3.org/TR/sparql11-update/#deleteInsert + */ + public function testDeleteToUpdateEndpointOnMockedHttpRequest( $httpDatabaseConnector, $expectedPostField ) { + + $httpRequest = $this->getMockBuilder( '\SMW\HttpRequest' ) + ->disableOriginalConstructor() + ->getMock(); + + $httpRequest->expects( $this->at( 2 ) ) + ->method( 'setOption' ) + ->with( + $this->equalTo( CURLOPT_POSTFIELDS ), + $this->stringContains( $expectedPostField ) ) + ->will( $this->returnValue( true ) ); + + $httpRequest->expects( $this->once() ) + ->method( 'getLastErrorCode' ) + ->will( $this->returnValue( 0 ) ); + + $instance = new $httpDatabaseConnector( + 'http://foo/myDefaultGraph', + 'http://localhost:9999/query', + 'http://localhost:9999/update' + ); + + $instance->setHttpRequest( $httpRequest ); + + $this->assertTrue( $instance->delete( 'wiki:Foo ?p ?o', 'wiki:Foo ?p ?o' ) ); + } + + /** + * @dataProvider httpDatabaseConnectorInstanceNameForInsertProvider + * + * @see http://www.w3.org/TR/sparql11-http-rdf-update/#http-post + */ + public function testInsertViaHttpPostToDataPointOnMockedHttpRequest( $httpDatabaseConnector ) { + + $httpRequest = $this->getMockBuilder( '\SMW\HttpRequest' ) + ->disableOriginalConstructor() + ->getMock(); + + $httpRequest->expects( $this->once() ) + ->method( 'getLastErrorCode' ) + ->will( $this->returnValue( 0 ) ); + + $instance = new $httpDatabaseConnector( + 'http://foo/myDefaultGraph', + 'http://localhost:9999/query', + 'http://localhost:9999/update', + 'http://localhost:9999/data' + ); + + $instance->setHttpRequest( $httpRequest ); + + $this->assertTrue( $instance->insertData( 'property:Foo wiki:Bar;' ) ); + } + + public function httpDatabaseConnectorInstanceNameForAskProvider() { + + $provider = array(); + $encodedDefaultGraph = urlencode( 'http://foo/myDefaultGraph' ); + + foreach ( $this->databaseConnectors as $databaseConnector ) { + + switch ( $databaseConnector ) { + case '\SMW\SPARQLStore\FusekiHttpDatabaseConnector': + $expectedPostField = '&default-graph-uri=' . $encodedDefaultGraph . '&output=xml'; + break; + case 'SMWSparqlDatabase4Store': + case '\SMW\SPARQLStore\FourstoreHttpDatabaseConnector': + $expectedPostField = "&restricted=1" . '&default-graph-uri=' . $encodedDefaultGraph; + break; + default: + $expectedPostField = '&default-graph-uri=' . $encodedDefaultGraph; + break; + }; + + $provider[] = array( $databaseConnector, $expectedPostField ); + } + + return $provider; + } + + public function httpDatabaseConnectorInstanceNameForDeleteProvider() { + + $provider = array(); + + foreach ( $this->databaseConnectors as $databaseConnector ) { + + switch ( $databaseConnector ) { + case 'SMWSparqlDatabaseVirtuoso': + case '\SMW\SPARQLStore\VirtuosoHttpDatabaseConnector': + $expectedPostField = 'query='; + break; + default: + $expectedPostField = 'update='; + break; + }; + + $provider[] = array( $databaseConnector, $expectedPostField ); + } + + return $provider; + } + + public function httpDatabaseConnectorInstanceNameForInsertProvider() { + + $provider = array(); + + foreach ( $this->databaseConnectors as $databaseConnector ) { + $provider[] = array( $databaseConnector ); + } + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/FalseConditionTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/FalseConditionTest.php new file mode 100644 index 00000000..27b9b2d5 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/FalseConditionTest.php @@ -0,0 +1,43 @@ +<?php + +namespace SMW\Tests\SPARQLStore\QueryEngine\Condition; + +use SMW\SPARQLStore\QueryEngine\Condition\FalseCondition; + +/** + * @covers \SMW\SPARQLStore\QueryEngine\Condition\FalseCondition + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class FalseConditionTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + 'SMW\SPARQLStore\QueryEngine\Condition\FalseCondition', + new FalseCondition() + ); + } + + public function testCommonMethods() { + + $instance = new FalseCondition(); + + $this->assertNotEmpty( + $instance->getCondition() + ); + + $this->assertTrue( + $instance->isSafe() + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/FilterConditionTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/FilterConditionTest.php new file mode 100644 index 00000000..a6876d0c --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/FilterConditionTest.php @@ -0,0 +1,55 @@ +<?php + +namespace SMW\Tests\SPARQLStore\QueryEngine\Condition; + +use SMW\SPARQLStore\QueryEngine\Condition\FilterCondition; + +/** + * @covers \SMW\SPARQLStore\QueryEngine\Condition\FilterCondition + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class FilterConditionTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + 'SMW\SPARQLStore\QueryEngine\Condition\FilterCondition', + new FilterCondition( 'condition' ) + ); + } + + public function testCommonMethods() { + + $instance = new FilterCondition( 'filter' ); + + $this->assertInternalType( + 'string', + $instance->getCondition() + ); + + $this->assertInternalType( + 'array', + $instance->namespaces + ); + + $this->assertInternalType( + 'string', + $instance->getWeakConditionString() + ); + + $this->assertInternalType( + 'boolean', + $instance->isSafe() + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/SingletonConditionTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/SingletonConditionTest.php new file mode 100644 index 00000000..4f0c7358 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/SingletonConditionTest.php @@ -0,0 +1,58 @@ +<?php + +namespace SMW\Tests\SPARQLStore\QueryEngine\Condition; + +use SMW\SPARQLStore\QueryEngine\Condition\SingletonCondition; + +/** + * @covers \SMW\SPARQLStore\QueryEngine\Condition\SingletonCondition + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class SingletonConditionTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $expElement = $this->getMockBuilder( '\SMWExpElement' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + 'SMW\SPARQLStore\QueryEngine\Condition\SingletonCondition', + new SingletonCondition( $expElement ) + ); + } + + public function testCommonMethods() { + + $expElement = $this->getMockBuilder( '\SMWExpElement' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new SingletonCondition( $expElement ); + + $this->assertInternalType( + 'string', + $instance->getCondition() + ); + + $this->assertInternalType( + 'string', + $instance->getWeakConditionString() + ); + + $this->assertInternalType( + 'boolean', + $instance->isSafe() + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/TrueConditionTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/TrueConditionTest.php new file mode 100644 index 00000000..a565df39 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/TrueConditionTest.php @@ -0,0 +1,43 @@ +<?php + +namespace SMW\Tests\SPARQLStore\QueryEngine\Condition; + +use SMW\SPARQLStore\QueryEngine\Condition\TrueCondition; + +/** + * @covers \SMW\SPARQLStore\QueryEngine\Condition\TrueCondition + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class TrueConditionTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + 'SMW\SPARQLStore\QueryEngine\Condition\TrueCondition', + new TrueCondition() + ); + } + + public function testCommonMethods() { + + $instance = new TrueCondition(); + + $this->assertEmpty( + $instance->getCondition() + ); + + $this->assertFalse( + $instance->isSafe() + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/WhereConditionTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/WhereConditionTest.php new file mode 100644 index 00000000..f552c1c5 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/WhereConditionTest.php @@ -0,0 +1,55 @@ +<?php + +namespace SMW\Tests\SPARQLStore\QueryEngine\Condition; + +use SMW\SPARQLStore\QueryEngine\Condition\WhereCondition; + +/** + * @covers \SMW\SPARQLStore\QueryEngine\Condition\WhereCondition + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class WhereConditionTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + 'SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + new WhereCondition( 'condition', true ) + ); + } + + public function testCommonMethods() { + + $instance = new WhereCondition( 'condition', true ); + + $this->assertInternalType( + 'string', + $instance->getCondition() + ); + + $this->assertInternalType( + 'array', + $instance->namespaces + ); + + $this->assertInternalType( + 'string', + $instance->getWeakConditionString() + ); + + $this->assertInternalType( + 'boolean', + $instance->isSafe() + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/FederateResultListTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/FederateResultListTest.php new file mode 100644 index 00000000..a85d85f1 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/FederateResultListTest.php @@ -0,0 +1,128 @@ +<?php + +namespace SMW\Tests\SPARQLStore\QueryEngine; + +use SMW\SPARQLStore\QueryEngine\FederateResultList; + +use SMWExpLiteral as ExpLiteral; + +/** + * @covers \SMW\SPARQLStore\QueryEngine\FederateResultList + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class FederateResultListTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\FederateResultList', + new FederateResultList( array(), array() ) + ); + + $this->assertInstanceOf( + '\Iterator', + new FederateResultList( array(), array() ) + ); + } + + public function testIsBooleanTrue() { + + $instance = new FederateResultList( + array(), + array( array( new ExpLiteral( 'true', 'http://www.w3.org/2001/XMLSchema#boolean' ) ) ) + ); + + $this->assertEquals( 1, $instance->numRows() ); + $this->assertTrue( $instance->isBooleanTrue() ); + } + + public function testIsBooleanNotTrue() { + + $instance = new FederateResultList( + array(), + array() + ); + + $this->assertFalse( $instance->isBooleanTrue() ); + } + + public function testGetNumericValue() { + + $instance = new FederateResultList( + array(), + array( array( new ExpLiteral( '2', 'http://www.w3.org/2001/XMLSchema#integer' ) ) ) + ); + + $this->assertEquals( 1, $instance->numRows() ); + $this->assertSame( 2, $instance->getNumericValue() ); + } + + public function testGetZeroNumericValue() { + + $instance = new FederateResultList( + array(), + array() + ); + + $this->assertSame( 0, $instance->getNumericValue() ); + } + + public function testSetGetErrorCode() { + + $instance = new FederateResultList( + array(), + array() + ); + + $instance->setErrorCode( FederateResultList::ERROR_INCOMPLETE ); + + $this->assertEquals( + FederateResultList::ERROR_INCOMPLETE, + $instance->getErrorCode() + ); + } + + public function testIteration() { + + $rawList = array( + array( + new ExpLiteral( '2', 'http://www.w3.org/2001/XMLSchema#integer' ), + new ExpLiteral( 'true', 'http://www.w3.org/2001/XMLSchema#boolean' ) + ), + array( + new ExpLiteral( '2', 'http://www.w3.org/2001/XMLSchema#integer' ) + ) + ); + + $instance = new FederateResultList( + array(), + array( $rawList[0], $rawList[1] ) + ); + + foreach ( $instance as $key => $listItem ) { + $this->assertEquals( $rawList[ $key ], $listItem ); + } + } + + public function testGetComments() { + + $instance = new FederateResultList( + array(), + array(), + array( 'Foo' ) + ); + + $this->assertContains( 'Foo', $instance->getComments() ); + } + +} + diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/QueryConditionBuilderTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/QueryConditionBuilderTest.php new file mode 100644 index 00000000..f4f684ff --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/QueryConditionBuilderTest.php @@ -0,0 +1,558 @@ +<?php + +namespace SMW\Tests\SPARQLStore\QueryEngine; + +use SMW\Tests\Util\StringBuilder; + +use SMW\SPARQLStore\QueryEngine\QueryConditionBuilder; +use SMW\DIProperty; +use SMW\DIWikiPage; + +use SMWDINumber as DINumber; +use SMWDIBlob as DIBlob; +use SMWDITime as DITime; +use SMWValueDescription as ValueDescription; +use SMWSomeProperty as SomeProperty; +use SMWPrintRequest as PrintRequest; +use SMWPropertyValue as PropertyValue; +use SMWThingDescription as ThingDescription; +use SMWConjunction as Conjunction; +use SMWDisjunction as Disjunction; +use SMWClassDescription as ClassDescription; +use SMWNamespaceDescription as NamespaceDescription; + +/** + * @covers \SMW\SPARQLStore\QueryEngine\QueryConditionBuilder + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-sparql + * @group semantic-mediawiki-query + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class QueryConditionBuilderTest extends \PHPUnit_Framework_TestCase { + + private $stringBuilder; + + protected function setUp() { + parent::setUp(); + + $this->stringBuilder = new StringBuilder(); + } + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\QueryConditionBuilder', + new QueryConditionBuilder() + ); + } + + public function testQueryForSingleProperty() { + + $property = new DIProperty( 'Foo' ); + + $description = new SomeProperty( + $property, + new ThingDescription() + ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $description ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '?result property:Foo ?v1 .' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + public function testQueryForSinglePropertyWithValue() { + + $description = new ValueDescription( + new DIBlob( 'SomePropertyValue' ), + new DIProperty( 'Foo' ) + ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $description ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\SingletonCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '"SomePropertyValue" swivt:page ?url .' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + public function testQueryForSomePropertyWithValue() { + + $property = new DIProperty( 'Foo' ); + + $description = new SomeProperty( + $property, + new ValueDescription( new DIBlob( 'SomePropertyBlobValue' ) ) + ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $description ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '?result property:Foo "SomePropertyBlobValue" .' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + public function testQueryForSinglePageTypePropertyWithValueComparator() { + + $property = new DIProperty( 'Foo' ); + $property->setPropertyTypeId( '_wpg' ); + + $description = new SomeProperty( + $property, + new ValueDescription( new DIWikiPage( 'SomePropertyPageValue', NS_MAIN ), null, SMW_CMP_LEQ ) + ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $description ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '?result property:Foo ?v1 .' )->addNewLine() + ->addString( 'FILTER( ?v1sk <= "SomePropertyPageValue" )' )->addNewLine() + ->addString( '?v1 swivt:wikiPageSortKey ?v1sk .' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + public function testQueryForSingleBlobTypePropertyWithNotLikeComparator() { + + $property = new DIProperty( 'Foo' ); + $property->setPropertyTypeId( '_txt' ); + + $description = new SomeProperty( + $property, + new ValueDescription( new DIBlob( 'SomePropertyBlobValue' ), null, SMW_CMP_NLKE ) + ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $description ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '?result property:Foo ?v1 .' )->addNewLine() + ->addString( 'FILTER( !regex( ?v1, "^SomePropertyBlobValue$", "s") )' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + public function testQueryForSingleCategory() { + + $description = new ClassDescription( + new DIWikiPage( 'Foo', NS_CATEGORY, '' ) + ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $description ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( "{ ?result rdf:type wiki:Category-3AFoo . }" )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + public function testQueryForSingleNamespace() { + + $description = new NamespaceDescription( NS_HELP ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $description ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $this->assertSame( 12, NS_HELP ); + + $expectedConditionString = $this->stringBuilder + ->addString( '{ ?result swivt:wikiNamespace "12"^^xsd:integer . }' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + public function testQueryForPropertyConjunction() { + + $conjunction = new Conjunction( array( + new SomeProperty( + new DIProperty( 'Foo' ), new ValueDescription( new DIBlob( 'SomePropertyValue' ) ) ), + new SomeProperty( + new DIProperty( 'Bar' ), new ThingDescription() ), + ) ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $conjunction ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '?result property:Foo "SomePropertyValue" .' )->addNewLine() + ->addString( '?result property:Bar ?v2 .' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + public function testQueryForPropertyConjunctionWithGreaterLessEqualFilter() { + + $conjunction = new Conjunction( array( + new SomeProperty( + new DIProperty( 'Foo' ), + new ValueDescription( new DINumber( 1 ), null, SMW_CMP_GEQ ) ), + new SomeProperty( + new DIProperty( 'Bar' ), + new ValueDescription( new DINumber( 9 ), null, SMW_CMP_LEQ ) ), + ) ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $conjunction ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '?result property:Foo ?v1 .' )->addNewLine() + ->addString( 'FILTER( ?v1 >= "1"^^xsd:double )' )->addNewLine() + ->addString( '?result property:Bar ?v2 .' )->addNewLine() + ->addString( 'FILTER( ?v2 <= "9"^^xsd:double )' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + public function testQueryForPropertyDisjunction() { + + $conjunction = new Disjunction( array( + new SomeProperty( new DIProperty( 'Foo' ), new ThingDescription() ), + new SomeProperty( new DIProperty( 'Bar' ), new ThingDescription() ) + ) ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $conjunction ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '{' )->addNewLine() + ->addString( '?result property:Foo ?v1 .' )->addNewLine() + ->addString( '} UNION {' )->addNewLine() + ->addString( '?result property:Bar ?v2 .' )->addNewLine() + ->addString( '}' ) + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + public function testQueryForPropertyDisjunctionWithLikeNotLikeFilter() { + + $conjunction = new Disjunction( array( + new SomeProperty( + new DIProperty( 'Foo' ), + new ValueDescription( new DIBlob( "AA*" ), null, SMW_CMP_LIKE ) ), + new SomeProperty( + new DIProperty( 'Bar' ), + new ValueDescription( new DIBlob( "BB?" ), null, SMW_CMP_NLKE ) ) + ) ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $conjunction ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '{' )->addNewLine() + ->addString( '?result property:Foo ?v1 .' )->addNewLine() + ->addString( 'FILTER( regex( ?v1, "^AA.*$", "s") )' )->addNewLine() + ->addString( '} UNION {' )->addNewLine() + ->addString( '?result property:Bar ?v2 .' )->addNewLine() + ->addString( 'FILTER( !regex( ?v2, "^BB.$", "s") )' )->addNewLine() + ->addString( '}' ) + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + public function testSingleDatePropertyWithGreaterEqualConstraint() { + + $property = new DIProperty( 'SomeDateProperty' ); + $property->setPropertyTypeId( '_dat' ); + + $description = new SomeProperty( + $property, + new ValueDescription( new DITime( 1, 1970, 01, 01, 1, 1 ), null, SMW_CMP_GEQ ) + ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $description ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '?result property:SomeDateProperty-23aux ?v1 .' )->addNewLine() + ->addString( 'FILTER( ?v1 >= "2440587.5423611"^^xsd:double )' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + public function testSingleSubobjectBuildAsAuxiliaryProperty() { + + $property = new DIProperty( '_SOBJ' ); + + $description = new SomeProperty( + $property, + new ThingDescription() + ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $description ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '?result property:Has_subobject-23aux ?v1 .' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + /** + * '[[HasSomeProperty::Foo||Bar]]' + */ + public function testSubqueryDisjunction() { + + $property = new DIProperty( 'HasSomeProperty' ); + $property->setPropertyTypeId( '_wpg' ); + + $disjunction = new Disjunction( array( + new ValueDescription( new DIWikiPage( 'Foo', NS_MAIN ), $property ), + new ValueDescription( new DIWikiPage( 'Bar', NS_MAIN ), $property ) + ) ); + + $description = new SomeProperty( + $property, + $disjunction + ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $description ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '?result property:HasSomeProperty ?v1 .' )->addNewLine() + ->addString( 'FILTER( ?v1 = wiki:Foo || ?v1 = wiki:Bar )' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + /** + * '[[Born in::<q>[[Category:City]] [[Located in::Outback]]</q>]]' + */ + public function testNestedPropertyConjunction() { + + $property = DIProperty::newFromUserLabel( 'Born in' ); + $property->setPropertyTypeId( '_wpg' ); + + $conjunction = new Conjunction( array( + new ClassDescription( new DIWikiPage( 'City', NS_CATEGORY ) ), + new SomeProperty( + DIProperty::newFromUserLabel( 'Located in' ), + new ValueDescription( + new DIWikiPage( 'Outback', NS_MAIN ), + DIProperty::newFromUserLabel( 'Located in' ) ) + ) + ) + ); + + $description = new SomeProperty( + $property, + $conjunction + ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $description ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '?result property:Born_in ?v1 .' )->addNewLine() + ->addString( '{ ' ) + ->addString( '{ ?v1 rdf:type wiki:Category-3ACity . }' )->addNewLine() + ->addString( '?v1 property:Located_in wiki:Outback .' )->addNewLine() + ->addString( '}' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + + /** + * '[[LocatedIn.MemberOf::Wonderland]]' + */ + public function testPropertyChain() { + + $description = new SomeProperty( + DIProperty::newFromUserLabel( 'LocatedIn' ), + new SomeProperty( + DIProperty::newFromUserLabel( 'MemberOf' ), + new ValueDescription( + new DIWikiPage( 'Wonderland', NS_MAIN, '' ), + DIProperty::newFromUserLabel( 'MemberOf' ), SMW_CMP_EQ + ) + ) + ); + + $instance = new QueryConditionBuilder(); + + $condition = $instance->buildCondition( $description ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\Condition\WhereCondition', + $condition + ); + + $expectedConditionString = $this->stringBuilder + ->addString( '?result property:LocatedIn ?v1 .' )->addNewLine() + ->addString( '{ ?v1 property:MemberOf wiki:Wonderland .' )->addNewLine() + ->addString( '}' )->addNewLine() + ->getString(); + + $this->assertEquals( + $expectedConditionString, + $instance->convertConditionToString( $condition ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/QueryEngineTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/QueryEngineTest.php new file mode 100644 index 00000000..ad160108 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/QueryEngineTest.php @@ -0,0 +1,194 @@ +<?php + +namespace SMW\Tests\SPARQLStore\QueryEngine; + +use SMW\SPARQLStore\QueryEngine\QueryEngine; +use SMW\SPARQLStore\QueryEngine\ResultListConverter; + +use SMW\DIProperty; + +use SMWQuery as Query; + +/** + * @covers \SMW\SPARQLStore\QueryEngine\QueryEngine + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class QueryEngineTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $connection = $this->getMockBuilder( '\SMWSparqlDatabase' ) + ->disableOriginalConstructor() + ->getMock(); + + $queryConditionBuilder = $this->getMockBuilder( '\SMW\SPARQLStore\QueryEngine\QueryConditionBuilder' ) + ->disableOriginalConstructor() + ->getMock(); + + $resultListConverter = $this->getMockBuilder( '\SMW\SPARQLStore\QueryEngine\ResultListConverter' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\QueryEngine', + new QueryEngine( $connection, $queryConditionBuilder, $resultListConverter ) + ); + } + + public function testEmptyGetQueryResultWhereQueryContainsErrors() { + + $connection = $this->getMockBuilder( '\SMWSparqlDatabase' ) + ->disableOriginalConstructor() + ->getMock(); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $queryConditionBuilder = $this->getMockBuilder( '\SMW\SPARQLStore\QueryEngine\QueryConditionBuilder' ) + ->disableOriginalConstructor() + ->getMock(); + + $description = $this->getMockForAbstractClass( '\SMWDescription' ); + + $instance = new QueryEngine( $connection, $queryConditionBuilder, new ResultListConverter( $store ) ); + $instance->setIgnoreQueryErrors( false ); + + $query = new Query( $description ); + $query->addErrors( array( 'Foo' ) ); + + $this->assertInstanceOf( + '\SMWQueryResult', + $instance->getQueryResult( $query ) + ); + + $this->assertEmpty( + $instance->getQueryResult( $query )->getResults() + ); + } + + public function testEmptyGetQueryResultWhereQueryModeIsNone() { + + $connection = $this->getMockBuilder( '\SMWSparqlDatabase' ) + ->disableOriginalConstructor() + ->getMock(); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $queryConditionBuilder = $this->getMockBuilder( '\SMW\SPARQLStore\QueryEngine\QueryConditionBuilder' ) + ->disableOriginalConstructor() + ->getMock(); + + $description = $this->getMockForAbstractClass( '\SMWDescription' ); + + $instance = new QueryEngine( $connection, $queryConditionBuilder, new ResultListConverter( $store ) ); + + $query = new Query( $description ); + $query->querymode = Query::MODE_NONE; + + $this->assertInstanceOf( + '\SMWQueryResult', + $instance->getQueryResult( $query ) + ); + + $this->assertEmpty( + $instance->getQueryResult( $query )->getResults() + ); + } + + public function testGetQueryResultWhereQueryModeIsDebug() { + + $connection = $this->getMockBuilder( '\SMWSparqlDatabase' ) + ->disableOriginalConstructor() + ->getMock(); + + $condition = $this->getMockForAbstractClass( '\SMW\SPARQLStore\QueryEngine\Condition\Condition' ); + + $queryConditionBuilder = $this->getMockBuilder( '\SMW\SPARQLStore\QueryEngine\QueryConditionBuilder' ) + ->disableOriginalConstructor() + ->getMock(); + + $queryConditionBuilder->expects( $this->atLeastOnce() ) + ->method( 'setSortKeys' ) + ->will( $this->returnValue( $queryConditionBuilder ) ); + + $queryConditionBuilder->expects( $this->atLeastOnce() ) + ->method( 'buildCondition' ) + ->will( $this->returnValue( $condition ) ); + + $resultListConverter = $this->getMockBuilder( '\SMW\SPARQLStore\QueryEngine\ResultListConverter' ) + ->disableOriginalConstructor() + ->getMock(); + + $description = $this->getMockForAbstractClass( '\SMWDescription' ); + + $instance = new QueryEngine( $connection, $queryConditionBuilder, $resultListConverter ); + + $query = new Query( $description ); + $query->querymode = Query::MODE_DEBUG; + + $this->assertNotInstanceOf( + '\SMWQueryResult', + $instance->getQueryResult( $query ) + ); + + $this->assertInternalType( + 'string', + $instance->getQueryResult( $query ) + ); + } + + public function testGetSuccessCountQueryResultForMockedCompostion() { + + $federateResultList = $this->getMockBuilder( '\SMW\SPARQLStore\QueryEngine\FederateResultList' ) + ->disableOriginalConstructor() + ->getMock(); + + $connection = $this->getMockBuilder( '\SMWSparqlDatabase' ) + ->disableOriginalConstructor() + ->getMock(); + + $connection->expects( $this->once() ) + ->method( 'selectCount' ) + ->will( $this->returnValue( $federateResultList ) ); + + $condition = $this->getMockForAbstractClass( '\SMW\SPARQLStore\QueryEngine\Condition\Condition' ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $queryConditionBuilder = $this->getMockBuilder( '\SMW\SPARQLStore\QueryEngine\QueryConditionBuilder' ) + ->disableOriginalConstructor() + ->getMock(); + + $queryConditionBuilder->expects( $this->atLeastOnce() ) + ->method( 'setSortKeys' ) + ->will( $this->returnValue( $queryConditionBuilder ) ); + + $queryConditionBuilder->expects( $this->once() ) + ->method( 'buildCondition' ) + ->will( $this->returnValue( $condition ) ); + + $description = $this->getMockForAbstractClass( '\SMWDescription' ); + + $instance = new QueryEngine( $connection, $queryConditionBuilder, new ResultListConverter( $store ) ); + + $this->assertInstanceOf( + '\SMWQueryResult', + $instance->getCountQueryResult( new Query( $description ) ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/RawResultParserTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/RawResultParserTest.php new file mode 100644 index 00000000..87431cf3 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/RawResultParserTest.php @@ -0,0 +1,151 @@ +<?php + +namespace SMW\Tests\SPARQLStore\QueryEngine; + +use SMW\Tests\Util\FakeRawResultProvider; +use SMW\SPARQLStore\QueryEngine\RawResultParser; + +use SMWExpResource as ExpResource; +use SMWExpLiteral as ExpLiteral; + +/** + * @covers \SMW\SPARQLStore\QueryEngine\RawResultParser + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-sparql + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class RawResultParserTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\RawResultParser', + new RawResultParser() + ); + } + + /** + * @dataProvider rawXmlResultDocumentProvider + */ + public function testXmlParse( $rawXmlResult, $expectedResultRowItemInstance ) { + + $instance = new RawResultParser(); + $resultFormat = $instance->parse( $rawXmlResult ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\FederateResultList', + $resultFormat + ); + + $this->assertResultFormat( + $expectedResultRowItemInstance, + $resultFormat + ); + } + + public function testInvalidXmlThrowsException() { + + $rawResultProvider = new FakeRawResultProvider(); + + $instance = new RawResultParser(); + + $this->setExpectedException( 'RuntimeException' ); + $instance->parse( $rawResultProvider->getInvalidSparqlResultXml() ); + } + + protected function assertResultFormat( $expectedResultRowItemInstance, $results ) { + + if ( !is_array( $expectedResultRowItemInstance ) ) { + $expectedResultRowItemInstance = array( $expectedResultRowItemInstance ); + } + + foreach ( $results as $key => $row ) { + $this->assertResultRow( $expectedResultRowItemInstance[ $key ], $row ); + } + } + + protected function assertResultRow( $expectedItemInstance, $row ) { + + foreach ( $row as $key => $item ) { + + if ( $item === null ) { + continue; + } + + $this->assertEquals( $expectedItemInstance, $item ); + } + } + + public function rawXmlResultDocumentProvider() { + + $rawResultProvider = new FakeRawResultProvider(); + + #0 + $provider[] = array( + $rawResultProvider->getUriResourceSparqlResultXml(), + new ExpResource( 'http://example.org/id/Foo' ) + ); + + #1 + $provider[] = array( + $rawResultProvider->getEmptySparqlResultXml(), + null + ); + + #2 @bug 62218 + $provider[] = array( + $rawResultProvider->getNonTypeLiteralResultXml(), + new ExpLiteral( 'Has foo' ) + ); + + #3 + $provider[] = array( + $rawResultProvider->getBooleanSparqlResultXml(), + new ExpLiteral( 'true', 'http://www.w3.org/2001/XMLSchema#boolean' ) + ); + + #4 + $provider[] = array( + $rawResultProvider->getStringTypeLiteralSparqlResultXml(), + new ExpLiteral( 'Foo', 'http://www.w3.org/2001/XMLSchema#string' ) + ); + + #5 + $provider[] = array( + $rawResultProvider->getIntegerTypeLiteralSparqlResultXml(), + new ExpLiteral( '1', 'http://www.w3.org/2001/XMLSchema#integer' ) + ); + + #6 + $provider[] = array( + $rawResultProvider->getMixedRowsSparqlResultXml(), + array( + new ExpResource( 'http://example.org/id/Foo' ), + new ExpResource( 'http://example.org/id/Bar' ), + new ExpLiteral( 'Quux', 'http://www.w3.org/2001/XMLSchema#string' ) + ) + ); + + #7 #450 + $provider[] = array( + false, + null + ); + + #8 #450 + $provider[] = array( + 'false', + null + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/ResultListConverterTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/ResultListConverterTest.php new file mode 100644 index 00000000..2eda0f9b --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/ResultListConverterTest.php @@ -0,0 +1,188 @@ +<?php + +namespace SMW\Tests\SPARQLStore\QueryEngine; + +use SMW\Tests\Util\Mock\IteratorMockBuilder; + +use SMW\SPARQLStore\QueryEngine\ResultListConverter; + +use SMWQuery as Query; +use SMWQueryResult as QueryResult; + +/** + * @covers \SMW\SPARQLStore\QueryEngine\ResultListConverter + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-sparql + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class ResultListConverterTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\QueryEngine\ResultListConverter', + new ResultListConverter( $store ) + ); + } + + /** + * @dataProvider sparqlResultListErrorCodeProvider + */ + public function testGetQueryResultObjectForCountQuery( $errorCode ) { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $federateResultList = $this->getMockBuilder( '\SMW\SPARQLStore\QueryEngine\FederateResultList' ) + ->disableOriginalConstructor() + ->getMock(); + + $federateResultList->expects( $this->atLeastOnce() ) + ->method( 'getErrorCode' ) + ->will( $this->returnValue( $errorCode ) ); + + $description = $this->getMockBuilder( '\SMWDescription' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $query = new Query( $description ); + $query->querymode = Query::MODE_COUNT; + + $instance = new ResultListConverter( $store ); + + $this->assertInstanceOf( + '\SMWQueryResult', + $instance->convertToQueryResult( $federateResultList, $query ) + ); + + $this->assertQueryResultErrorCodeForCountValue( + $errorCode, + $instance->convertToQueryResult( $federateResultList, $query ) + ); + } + + /** + * @dataProvider sparqlResultListErrorCodeProvider + */ + public function testGetQueryResultObjectForEmptyInstanceQuery( $errorCode ) { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $federateResultList = $this->getMockBuilder( '\SMW\SPARQLStore\QueryEngine\FederateResultList' ) + ->disableOriginalConstructor() + ->getMock(); + + $federateResultList->expects( $this->atLeastOnce() ) + ->method( 'getErrorCode' ) + ->will( $this->returnValue( $errorCode ) ); + + $description = $this->getMockBuilder( '\SMWDescription' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $query = new Query( $description ); + $query->querymode = Query::MODE_INSTANCES; + + $instance = new ResultListConverter( $store ); + + $this->assertInstanceOf( + '\SMWQueryResult', + $instance->convertToQueryResult( $federateResultList, $query ) + ); + + $this->assertQueryResultErrorCode( + $errorCode, + $instance->convertToQueryResult( $federateResultList, $query ) + ); + } + + /** + * @dataProvider sparqlResultListErrorCodeProvider + */ + public function testGetQueryResultObjectForInstanceQuery( $errorCode ) { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $expElement = $this->getMockBuilder( '\SMWExpElement' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $iteratorMockBuilder = new IteratorMockBuilder(); + + $federateResultList = $iteratorMockBuilder->setClass( '\SMW\SPARQLStore\QueryEngine\FederateResultList' ) + ->with( array( array( $expElement ) ) ) + ->getMockForIterator(); + + $federateResultList->expects( $this->atLeastOnce() ) + ->method( 'getErrorCode' ) + ->will( $this->returnValue( $errorCode ) ); + + $description = $this->getMockBuilder( '\SMWDescription' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $query = new Query( $description ); + $query->querymode = Query::MODE_INSTANCES; + + $instance = new ResultListConverter( $store ); + + $this->assertInstanceOf( + '\SMWQueryResult', + $instance->convertToQueryResult( $federateResultList, $query ) + ); + + $this->assertQueryResultErrorCode( + $errorCode, + $instance->convertToQueryResult( $federateResultList, $query ) + ); + } + + private function assertQueryResultErrorCodeForCountValue( $errorCode, QueryResult $queryResult ) { + + if ( $errorCode > 0 ) { + $this->assertNotEmpty( $queryResult->getErrors() ); + return $this->assertNull( $queryResult->getCountValue() ); + } + + $this->assertEmpty( $queryResult->getErrors() ); + $this->assertInternalType( 'integer', $queryResult->getCountValue() ); + } + + private function assertQueryResultErrorCode( $errorCode, QueryResult $queryResult ) { + + if ( $errorCode > 0 ) { + return $this->assertNotEmpty( $queryResult->getErrors() ); + } + + $this->assertEmpty( $queryResult->getErrors() ); + } + + public function sparqlResultListErrorCodeProvider() { + + $provider = array( + array( 0 ), + array( 1 ), + array( 2 ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/RedirectLookupTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/RedirectLookupTest.php new file mode 100644 index 00000000..696f3bbc --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/RedirectLookupTest.php @@ -0,0 +1,215 @@ +<?php + +namespace SMW\Tests\SPARQLStore; + +use SMW\SPARQLStore\RedirectLookup; +use SMW\DIWikiPage; +use SMW\DIProperty; + +use SMWExpNsResource as ExpNsResource; +use SMWExpLiteral as ExpLiteral; +use SMWExpResource as ExpResource; +use SMWExporter as Exporter; + +/** + * @covers \SMW\SPARQLStore\RedirectLookup + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class RedirectLookupTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $sparqlDatabase = $this->getMockBuilder( '\SMWSparqlDatabase' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\RedirectLookup', + new RedirectLookup( $sparqlDatabase ) + ); + } + + public function testRedirectTragetForBlankNode() { + + $sparqlDatabase = $this->getMockBuilder( '\SMWSparqlDatabase' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new RedirectLookup( $sparqlDatabase ); + + $expNsResource = new ExpNsResource( '', '', '', null ); + $exists = null; + + $this->assertSame( + $expNsResource, + $instance->findRedirectTargetResource( $expNsResource, $exists ) + ); + + $this->assertFalse( $exists ); + } + + public function testRedirectTragetForDataItemWithSubobject() { + + $sparqlDatabase = $this->getMockBuilder( '\SMWSparqlDatabase' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new RedirectLookup( $sparqlDatabase ); + $dataItem = new DIWikiPage( 'Foo', 1, '', 'beingASubobject' ); + + $expNsResource = new ExpNsResource( 'Foo', 'Bar', '', $dataItem ); + $exists = null; + + $this->assertSame( + $expNsResource, + $instance->findRedirectTargetResource( $expNsResource, $exists ) + ); + + $this->assertTrue( $exists ); + } + + public function testRedirectTragetForDBLookupWithNoEntry() { + + $sparqlDatabase = $this->createMockSparqlDatabaseFor( false ); + + $instance = new RedirectLookup( $sparqlDatabase ); + $dataItem = new DIWikiPage( 'Foo', 1, '', '' ); + + $expNsResource = new ExpNsResource( 'Foo', 'Bar', '', $dataItem ); + $exists = null; + + $this->assertSame( + $expNsResource, + $instance->findRedirectTargetResource( $expNsResource, $exists ) + ); + + $this->assertFalse( $exists ); + } + + public function testRedirectTragetForDBLookupWithSingleEntry() { + + $expLiteral = new ExpLiteral( 'Redirect' ); + + $sparqlDatabase = $this->createMockSparqlDatabaseFor( array( $expLiteral ) ); + + $instance = new RedirectLookup( $sparqlDatabase ); + $dataItem = new DIWikiPage( 'Foo', 1, '', '' ); + + $expNsResource = new ExpNsResource( 'Foo', 'Bar', '', $dataItem ); + $exists = null; + + $this->assertSame( + $expNsResource, + $instance->findRedirectTargetResource( $expNsResource, $exists ) + ); + + $this->assertTrue( $exists ); + } + + public function testRedirectTragetForDBLookupWithMultipleEntries() { + + $expLiteral = new ExpLiteral( 'Redirect' ); + + $sparqlDatabase = $this->createMockSparqlDatabaseFor( array( $expLiteral, null ) ); + + $instance = new RedirectLookup( $sparqlDatabase ); + $dataItem = new DIWikiPage( 'Foo', 1, '', '' ); + + $expNsResource = new ExpNsResource( 'Foo', 'Bar', '', $dataItem ); + $exists = null; + + $this->assertSame( + $expNsResource, + $instance->findRedirectTargetResource( $expNsResource, $exists ) + ); + + $this->assertTrue( $exists ); + } + + public function testRedirectTragetForDBLookupWithMultipleEntriesForcesNewResource() { + + $propertyPage = new DIWikiPage( 'Foo', SMW_NS_PROPERTY ); + + $resource = new ExpNsResource( + 'Foo', + Exporter::getNamespaceUri( 'property' ), + 'property', + $propertyPage + ); + + $sparqlDatabase = $this->createMockSparqlDatabaseFor( array( $resource, $resource ) ); + + $instance = new RedirectLookup( $sparqlDatabase ); + $dataItem = new DIWikiPage( 'Foo', 1, '', '' ); + + $expNsResource = new ExpNsResource( 'Foo', 'Bar', '', $dataItem ); + $exists = null; + + $targetResource = $instance->findRedirectTargetResource( $expNsResource, $exists ); + + $this->assertNotSame( + $expNsResource, + $targetResource + ); + + $expectedResource = new ExpNsResource( + Exporter::getInstance()->getEncodedPageName( $propertyPage ), + Exporter::getNamespaceUri( 'wiki' ), + 'wiki' + ); + + $this->assertEquals( + $expectedResource, + $targetResource + ); + + $this->assertTrue( $exists ); + } + + public function testRedirectTragetForDBLookupWithForNonMultipleResourceEntryThrowsException() { + + $expLiteral = new ExpLiteral( 'Redirect' ); + + $sparqlDatabase = $this->createMockSparqlDatabaseFor( array( $expLiteral, $expLiteral ) ); + + $instance = new RedirectLookup( $sparqlDatabase ); + $dataItem = new DIWikiPage( 'Foo', 1, '', '' ); + + $expNsResource = new ExpNsResource( 'Foo', 'Bar', '', $dataItem ); + $exists = null; + + $this->setExpectedException( 'RuntimeException' ); + $instance->findRedirectTargetResource( $expNsResource, $exists ); + } + + private function createMockSparqlDatabaseFor( $listReturnValue ) { + + $federateResultList = $this->getMockBuilder( '\SMW\SPARQLStore\QueryEngine\FederateResultList' ) + ->disableOriginalConstructor() + ->getMock(); + + $federateResultList->expects( $this->once() ) + ->method( 'current' ) + ->will( $this->returnValue( $listReturnValue ) ); + + $sparqlDatabase = $this->getMockBuilder( '\SMWSparqlDatabase' ) + ->disableOriginalConstructor() + ->getMock(); + + $sparqlDatabase->expects( $this->once() ) + ->method( 'select' ) + ->will( $this->returnValue( $federateResultList ) ); + + return $sparqlDatabase; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/SparqlDBConnectionProviderTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/SparqlDBConnectionProviderTest.php new file mode 100644 index 00000000..2a01df39 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/SparqlDBConnectionProviderTest.php @@ -0,0 +1,204 @@ +<?php + +namespace SMW\Tests\SPARQLStore; + +use SMW\SPARQLStore\SparqlDBConnectionProvider; +use SMW\Configuration\Configuration; + +/** + * @covers \SMW\SPARQLStore\SparqlDBConnectionProvider + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-sparql + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class SparqlDBConnectionProviderTest extends \PHPUnit_Framework_TestCase { + + private $configuration; + private $smwgSparqlDatabase; + private $smwgSparqlDatabaseConnector; + + protected function setUp() { + parent::setUp(); + + $this->configuration = Configuration::getInstance(); + + $this->smwgSparqlDatabaseConnector = $this->configuration->get( 'smwgSparqlDatabaseConnector' ); + $this->smwgSparqlDatabase = $this->configuration->get( 'smwgSparqlDatabase' ); + } + + protected function tearDown() { + + $this->configuration->set( + 'smwgSparqlDatabaseConnector', + $this->smwgSparqlDatabaseConnector + ); + + $this->configuration->set( + 'smwgSparqlDatabase', + $this->smwgSparqlDatabase + ); + } + + public function testCanConstruct() { + + $instance = new SparqlDBConnectionProvider(); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\SparqlDBConnectionProvider', + $instance + ); + + $this->assertInstanceOf( + '\SMW\DBConnectionProvider', + $instance + ); + } + + public function testGetDefaultConnection() { + + $instance = new SparqlDBConnectionProvider( 'default' ); + + $this->assertInstanceOf( + '\SMWSparqlDatabase', + $instance->getConnection() + ); + + $connection = $instance->getConnection(); + + $this->assertSame( + $connection, + $instance->getConnection() + ); + + $instance->releaseConnection(); + + $this->assertNotSame( + $connection, + $instance->getConnection() + ); + } + + public function testGetFusekiConnection() { + + $instance = new SparqlDBConnectionProvider( 'fuSEKi' ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\FusekiHttpDatabaseConnector', + $instance->getConnection() + ); + } + + public function testGetVirtuosoConnection() { + + $instance = new SparqlDBConnectionProvider( 'virtuoso' ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\VirtuosoHttpDatabaseConnector', + $instance->getConnection() + ); + + // Legacy + $this->assertInstanceOf( + '\SMWSparqlDatabaseVirtuoso', + $instance->getConnection() + ); + } + + public function testGet4StoreConnection() { + + $instance = new SparqlDBConnectionProvider( '4STORE' ); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\FourstoreHttpDatabaseConnector', + $instance->getConnection() + ); + + // Legacy + $this->assertInstanceOf( + '\SMWSparqlDatabase4Store', + $instance->getConnection() + ); + } + + public function testGetDefaultConnectorForUnknownConnectorId() { + + $this->configuration->set( + 'smwgSparqlDatabaseConnector', + 'default' + ); + + $instance = new SparqlDBConnectionProvider( 'foo' ); + + $this->assertInstanceOf( + '\SMWSparqlDatabase', + $instance->getConnection() + ); + } + + public function testGetDefaultConnectorForEmptyConnectorId() { + + $this->configuration->set( + 'smwgSparqlDatabaseConnector', + 'default' + ); + + $instance = new SparqlDBConnectionProvider(); + + $this->assertInstanceOf( + '\SMWSparqlDatabase', + $instance->getConnection() + ); + } + + public function testGetDefaultConnectorForUnMappedId() { + + $this->configuration->set( + 'smwgSparqlDatabaseConnector', + 'idThatCanNotBeMapped' + ); + + $instance = new SparqlDBConnectionProvider(); + + $this->assertInstanceOf( + '\SMWSparqlDatabase', + $instance->getConnection() + ); + } + + public function testInvalidCustomClassConnectorThrowsException() { + + $this->configuration->set( + 'smwgSparqlDatabase', + 'InvalidCustomClassConnector' + ); + + $instance = new SparqlDBConnectionProvider( 'custom' ); + + $this->setExpectedException( 'RuntimeException' ); + $instance->getConnection(); + } + + public function testInvalidCustomSparqlClassConnectorThrowsException() { + + $this->configuration->set( + 'smwgSparqlDatabase', + '\SMW\Tests\SPARQLStore\InvalidCustomSparqlClassConnector' + ); + + $instance = new SparqlDBConnectionProvider( 'custom' ); + + $this->setExpectedException( 'RuntimeException' ); + $instance->getConnection(); + } + +} + +class InvalidCustomSparqlClassConnector {} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/SparqlStoreTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/SparqlStoreTest.php new file mode 100644 index 00000000..53c19b02 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/SparqlStoreTest.php @@ -0,0 +1,140 @@ +<?php + +namespace SMW\Tests\SPARQLStore; + +use SMW\SPARQLStore\SPARQLStore; + +use SMW\DIWikiPage; +use SMW\SemanticData; + +use SMWExporter as Exporter; +use SMWTurtleSerializer as TurtleSerializer; + +use Title; + +/** + * @covers \SMW\SPARQLStore\SPARQLStore + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9.2 + * + * @author mwjames + */ +class SPARQLStoreTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\SPARQLStore\SPARQLStore', + new SPARQLStore() + ); + + // Legacy + $this->assertInstanceOf( + '\SMW\SPARQLStore\SPARQLStore', + new \SMWSPARQLStore() + ); + } + + public function testGetSemanticDataOnMockBaseStore() { + + $subject = DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ); + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $baseStore = $this->getMockBuilder( '\SMWStore' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $baseStore->expects( $this->once() ) + ->method( 'getSemanticData' ) + ->with( $this->equalTo( $subject ) ) + ->will( $this->returnValue( $semanticData ) ); + + $instance = new SPARQLStore( $baseStore ); + + $this->assertInstanceOf( + '\SMW\SemanticData', + $instance->getSemanticData( $subject ) + ); + } + + public function testDeleteSubjectOnMockBaseStore() { + + $title = Title::newFromText( 'DeleteSubjectOnMockBaseStore' ); + + $expResource = Exporter::getDataItemExpElement( DIWikiPage::newFromTitle( $title ) ); + $resourceUri = TurtleSerializer::getTurtleNameForExpElement( $expResource ); + + $extraNamespaces = array( + $expResource->getNamespaceId() => $expResource->getNamespace() + ); + + $baseStore = $this->getMockBuilder( '\SMWStore' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $baseStore->expects( $this->once() ) + ->method( 'deleteSubject' ) + ->with( $this->equalTo( $title ) ) + ->will( $this->returnValue( true ) ); + + $sparqlDatabase = $this->getMockBuilder( '\SMWSparqlDatabase' ) + ->disableOriginalConstructor() + ->getMock(); + + $sparqlDatabase->expects( $this->once() ) + ->method( 'deleteContentByValue' ) + ->will( $this->returnValue( true ) ); + + $sparqlDatabase->expects( $this->once() ) + ->method( 'delete' ) + ->with( + $this->equalTo( "{$resourceUri} ?p ?o" ), + $this->equalTo( "{$resourceUri} ?p ?o" ), + $this->equalTo( $extraNamespaces ) ) + ->will( $this->returnValue( true ) ); + + $instance = new SPARQLStore( $baseStore ); + $instance->setSparqlDatabase( $sparqlDatabase ); + + $instance->deleteSubject( $title ); + } + + public function testDoSparqlDataUpdateOnMockBaseStore() { + + $semanticData = new SemanticData( new DIWikiPage( 'Foo', NS_MAIN, '' ) ); + + $listReturnValue = $this->getMockBuilder( '\SMW\SPARQLStore\QueryEngine\FederateResultList' ) + ->disableOriginalConstructor() + ->getMock(); + + $baseStore = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $sparqlDatabase = $this->getMockBuilder( '\SMWSparqlDatabase' ) + ->disableOriginalConstructor() + ->getMock(); + + $sparqlDatabase->expects( $this->atLeastOnce() ) + ->method( 'select' ) + ->will( $this->returnValue( $listReturnValue ) ); + + $sparqlDatabase->expects( $this->once() ) + ->method( 'insertData' ); + + $instance = new SPARQLStore( $baseStore ); + $instance->setSparqlDatabase( $sparqlDatabase ); + + $instance->doSparqlDataUpdate( $semanticData ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/TurtleTriplesBuilderTest.php b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/TurtleTriplesBuilderTest.php new file mode 100644 index 00000000..7cc3db36 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/TurtleTriplesBuilderTest.php @@ -0,0 +1,69 @@ +<?php + +namespace SMW\Tests\SPARQLStore; + +use SMW\SPARQLStore\TurtleTriplesBuilder; +use SMW\SemanticData; +use SMW\DIWikiPage; + +use SMWExpNsResource as ExpNsResource; +use SMWExporter as Exporter; + +/** + * @covers \SMW\SPARQLStore\TurtleTriplesBuilder + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class TurtleTriplesBuilderTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $redirectLookup = $this->getMockBuilder( '\SMW\SPARQLStore\RedirectLookup' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\SPARQLStore\TurtleTriplesBuilder', + new TurtleTriplesBuilder( $semanticData, $redirectLookup ) + ); + } + + public function testBuildTriplesForEmptySemanticDataContainer() { + + $expNsResource = new ExpNsResource( + 'Redirect', + Exporter::getNamespaceUri( 'wiki' ), + 'Redirect' + ); + + $semanticData = new SemanticData( new DIWikiPage( 'Foo', NS_MAIN, '' ) ); + + $redirectLookup = $this->getMockBuilder( '\SMW\SPARQLStore\RedirectLookup' ) + ->disableOriginalConstructor() + ->getMock(); + + $redirectLookup->expects( $this->atLeastOnce() ) + ->method( 'findRedirectTargetResource' ) + ->will( $this->returnValue( $expNsResource ) ); + + $instance = new TurtleTriplesBuilder( $semanticData, $redirectLookup ); + + $this->assertTrue( $instance->doBuild()->hasTriplesForUpdate() ); + + $this->assertInternalType( 'string', $instance->getTriples() ); + $this->assertInternalType( 'array', $instance->getPrefixes() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SQLStore/SqlStoreWriterChangeTitleTest.php b/SemanticMediaWiki/tests/phpunit/includes/SQLStore/SqlStoreWriterChangeTitleTest.php new file mode 100644 index 00000000..36a5a6e3 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SQLStore/SqlStoreWriterChangeTitleTest.php @@ -0,0 +1,159 @@ +<?php + +namespace SMW\Tests\SQLStore; + +use \SMWSQLStore3Writers; +use SMW\SemanticData; +use SMW\DIWikiPage; + +use Title; + +/** + * @covers \SMWSQLStore3Writers + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-unit + * @group semantic-mediawiki-sqlstore + * @group mediawiki-databaseless + * + * @license GNU GPL v2+ + * @since 1.9.2 + * + * @author mwjames + */ +class SqlStoreWriterChangeTitleTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $parentStore = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMWSQLStore3Writers', + new SMWSQLStore3Writers( $parentStore ) + ); + } + + public function testChangeTitleForMainNamespaceWithoutRedirectId() { + + $objectIdGenerator = $this->getMockBuilder( '\SMWSql3SmwIds' ) + ->disableOriginalConstructor() + ->getMock(); + + $objectIdGenerator->expects( $this->at( 0 ) ) + ->method( 'getSMWPageID' ) + ->will( $this->returnValue( 1 ) ); + + $objectIdGenerator->expects( $this->at( 1 ) ) + ->method( 'getSMWPageID' ) + ->will( $this->returnValue( 5 ) ); + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->once() ) + ->method( 'select' ) + ->will( $this->returnValue( array() ) ); + + $database->expects( $this->once() ) + ->method( 'query' ) + ->will( $this->returnValue( true ) ); + + $database->expects( $this->atLeastOnce() ) + ->method( 'selectRow' ) + ->will( $this->returnValue( false ) ); + + $parentStore = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getObjectIds' ) + ->will( $this->returnValue( $objectIdGenerator ) ); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getPropertyTables' ) + ->will( $this->returnValue( array() ) ); + + $instance = new SMWSQLStore3Writers( $parentStore ); + + $instance->changeTitle( + Title::newFromText( __METHOD__ . '-old', NS_MAIN ), + Title::newFromText( __METHOD__ . '-new', NS_MAIN ), + 9999 + ); + } + + public function testChangeTitleForMainNamespaceWithRedirectId() { + + $row = new \stdClass; + $row->o_id = 5555; + + $objectIdGenerator = $this->getMockBuilder( '\SMWSql3SmwIds' ) + ->disableOriginalConstructor() + ->getMock(); + + $objectIdGenerator->expects( $this->at( 0 ) ) + ->method( 'getSMWPageID' ) + ->will( $this->returnValue( 1 ) ); + + $objectIdGenerator->expects( $this->at( 1 ) ) + ->method( 'getSMWPageID' ) + ->will( $this->returnValue( 5 ) ); + + $objectIdGenerator->expects( $this->atLeastOnce() ) + ->method( 'getSMWPropertyID' ) + ->will( $this->returnValue( 88 ) ); + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->once() ) + ->method( 'query' ) + ->will( $this->returnValue( true ) ); + + $database->expects( $this->once() ) + ->method( 'select' ) + ->will( $this->returnValue( array() ) ); + + $database->expects( $this->atLeastOnce() ) + ->method( 'selectRow' ) + ->will( $this->returnValue( $row ) ); + + $parentStore = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getObjectIds' ) + ->will( $this->returnValue( $objectIdGenerator ) ); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getPropertyTables' ) + ->will( $this->returnValue( array() ) ); + + $instance = new SMWSQLStore3Writers( $parentStore ); + + $instance->changeTitle( + Title::newFromText( __METHOD__ . '-old', NS_MAIN ), + Title::newFromText( __METHOD__ . '-new', NS_MAIN ), + 9999, + 1111 + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SQLStore/SqlStoreWriterDataUpdateTest.php b/SemanticMediaWiki/tests/phpunit/includes/SQLStore/SqlStoreWriterDataUpdateTest.php new file mode 100644 index 00000000..5c657d01 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SQLStore/SqlStoreWriterDataUpdateTest.php @@ -0,0 +1,208 @@ +<?php + +namespace SMW\Tests\SQLStore; + +use \SMWSQLStore3Writers; +use SMW\SemanticData; +use SMW\DIWikiPage; + +use Title; + +/** + * @covers \SMWSQLStore3Writers + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-unit + * @group semantic-mediawiki-sqlstore + * @group mediawiki-databaseless + * + * @license GNU GPL v2+ + * @since 1.9.2 + * + * @author mwjames + */ +class SqlStoreWriterDataUpdateTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $parentStore = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMWSQLStore3Writers', + new SMWSQLStore3Writers( $parentStore ) + ); + } + + public function testDoDataUpdateForMainNamespaceWithoutSubobject() { + + $title = Title::newFromText( __METHOD__, NS_MAIN ); + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->setConstructorArgs( array( DIWikiPage::newFromTitle( $title ) ) ) + ->setMethods( null ) + ->getMock(); + + $objectIdGenerator = $this->getMockBuilder( '\SMWSql3SmwIds' ) + ->disableOriginalConstructor() + ->getMock(); + + $objectIdGenerator->expects( $this->once() ) + ->method( 'getSMWPageIDandSort' ) + ->will( $this->returnValue( 0 ) ); + + $objectIdGenerator->expects( $this->once() ) + ->method( 'makeSMWPageID' ) + ->will( $this->returnValue( 0 ) ); + + $objectIdGenerator->expects( $this->once() ) + ->method( 'getPropertyTableHashes' ) + ->will( $this->returnValue( array() ) ); + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->once() ) + ->method( 'select' ) + ->will( $this->returnValue( array() ) ); + + $database->expects( $this->once() ) + ->method( 'selectRow' ) + ->will( $this->returnValue( false ) ); + + $parentStore = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getObjectIds' ) + ->will( $this->returnValue( $objectIdGenerator ) ); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getPropertyTables' ) + ->will( $this->returnValue( array() ) ); + + $instance = new SMWSQLStore3Writers( $parentStore ); + $instance->doDataUpdate( $semanticData ); + } + + public function testDoDataUpdateForConceptNamespaceWithoutSubobject() { + + $title = Title::newFromText( __METHOD__, SMW_NS_CONCEPT ); + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->setConstructorArgs( array( DIWikiPage::newFromTitle( $title ) ) ) + ->setMethods( null ) + ->getMock(); + + $objectIdGenerator = $this->getMockBuilder( '\SMWSql3SmwIds' ) + ->disableOriginalConstructor() + ->getMock(); + + $objectIdGenerator->expects( $this->once() ) + ->method( 'getSMWPageIDandSort' ) + ->will( $this->returnValue( 0 ) ); + + $objectIdGenerator->expects( $this->once() ) + ->method( 'makeSMWPageID' ) + ->will( $this->returnValue( 0 ) ); + + $objectIdGenerator->expects( $this->once() ) + ->method( 'getPropertyTableHashes' ) + ->will( $this->returnValue( array() ) ); + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->once() ) + ->method( 'select' ) + ->will( $this->returnValue( array() ) ); + + $database->expects( $this->atLeastOnce() ) + ->method( 'selectRow' ) + ->will( $this->returnValue( false ) ); + + $parentStore = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getObjectIds' ) + ->will( $this->returnValue( $objectIdGenerator ) ); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getPropertyTables' ) + ->will( $this->returnValue( array() ) ); + + $instance = new SMWSQLStore3Writers( $parentStore ); + $instance->doDataUpdate( $semanticData ); + } + + public function testDoDataUpdateForMainNamespaceWithRedirect() { + + $title = Title::newFromText( __METHOD__, NS_MAIN ); + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->setConstructorArgs( array( DIWikiPage::newFromTitle( $title ) ) ) + ->setMethods( array( 'getPropertyValues' ) ) + ->getMock(); + + $semanticData->expects( $this->once() ) + ->method( 'getPropertyValues' ) + ->will( $this->returnValue( array( DIWikiPage::newFromTitle( $title ) ) ) ); + + $objectIdGenerator = $this->getMockBuilder( '\SMWSql3SmwIds' ) + ->disableOriginalConstructor() + ->getMock(); + + $objectIdGenerator->expects( $this->once() ) + ->method( 'getSMWPageIDandSort' ) + ->will( $this->returnValue( 0 ) ); + + $objectIdGenerator->expects( $this->once() ) + ->method( 'makeSMWPageID' ) + ->will( $this->returnValue( 0 ) ); + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->once() ) + ->method( 'select' ) + ->will( $this->returnValue( array() ) ); + + $database->expects( $this->once() ) + ->method( 'selectRow' ) + ->will( $this->returnValue( false ) ); + + $parentStore = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getObjectIds' ) + ->will( $this->returnValue( $objectIdGenerator ) ); + + $parentStore->expects( $this->atLeastOnce() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $instance = new SMWSQLStore3Writers( $parentStore ); + $instance->doDataUpdate( $semanticData ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SQLStore/SqlStoreWriterDeleteSubjectTest.php b/SemanticMediaWiki/tests/phpunit/includes/SQLStore/SqlStoreWriterDeleteSubjectTest.php new file mode 100644 index 00000000..1032b5d0 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SQLStore/SqlStoreWriterDeleteSubjectTest.php @@ -0,0 +1,147 @@ +<?php + +namespace SMW\Tests\SQLStore; + +use \SMWSQLStore3Writers; + +use Title; + +/** + * @covers \SMWSQLStore3Writers + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-unit + * @group semantic-mediawiki-sqlstore + * @group mediawiki-databaseless + * + * @license GNU GPL v2+ + * @since 1.9.2 + * + * @author mwjames + */ +class SqlStoreWriterDeleteSubjectTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $parentStore = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMWSQLStore3Writers', + new SMWSQLStore3Writers( $parentStore ) + ); + } + + public function testDeleteSubjectForMainNamespace() { + + $title = Title::newFromText( __METHOD__, NS_MAIN ); + + $objectIdGenerator = $this->getMockBuilder( '\SMWSql3SmwIds' ) + ->disableOriginalConstructor() + ->getMock(); + + $objectIdGenerator->expects( $this->once() ) + ->method( 'getSMWPageIDandSort' ) + ->will( $this->returnValue( 0 ) ); + + $objectIdGenerator->expects( $this->once() ) + ->method( 'makeSMWPageID' ) + ->will( $this->returnValue( 0 ) ); + + $objectIdGenerator->expects( $this->once() ) + ->method( 'getPropertyTableHashes' ) + ->will( $this->returnValue( array() ) ); + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->once() ) + ->method( 'select' ) + ->will( $this->returnValue( array() ) ); + + $database->expects( $this->once() ) + ->method( 'selectRow' ) + ->will( $this->returnValue( false ) ); + + $parentStore = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $parentStore->expects( $this->exactly( 3 ) ) + ->method( 'getObjectIds' ) + ->will( $this->returnValue( $objectIdGenerator ) ); + + $parentStore->expects( $this->any() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $parentStore->expects( $this->exactly( 4 ) ) + ->method( 'getPropertyTables' ) + ->will( $this->returnValue( array() ) ); + + $instance = new SMWSQLStore3Writers( $parentStore ); + $instance->deleteSubject( $title ); + } + + public function testDeleteSubjectForConceptNamespace() { + + $title = Title::newFromText( __METHOD__, SMW_NS_CONCEPT ); + + $objectIdGenerator = $this->getMockBuilder( '\SMWSql3SmwIds' ) + ->disableOriginalConstructor() + ->getMock(); + + $objectIdGenerator->expects( $this->once() ) + ->method( 'getSMWPageID' ) + ->with( + $this->equalTo( $title->getDBkey() ), + $this->equalTo( $title->getNamespace() ), + $this->equalTo( $title->getInterwiki() ), + '', + false ) + ->will( $this->returnValue( 0 ) ); + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->once() ) + ->method( 'select' ) + ->will( $this->returnValue( array() ) ); + + $database->expects( $this->atLeastOnce() ) + ->method( 'selectRow' ) + ->will( $this->returnValue( false ) ); + + $database->expects( $this->exactly( 2 ) ) + ->method( 'delete' ) + ->will( $this->returnValue( true ) ); + + $parentStore = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $parentStore->expects( $this->any() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $parentStore->expects( $this->exactly( 4 ) ) + ->method( 'getObjectIds' ) + ->will( $this->returnValue( $objectIdGenerator ) ); + + $parentStore->expects( $this->exactly( 4 ) ) + ->method( 'getPropertyTables' ) + ->will( $this->returnValue( array() ) ); + + $parentStore->setDatabase( $database ); + + $instance = new SMWSQLStore3Writers( $parentStore ); + $instance->deleteSubject( $title ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SemanticDataTest.php b/SemanticMediaWiki/tests/phpunit/includes/SemanticDataTest.php new file mode 100644 index 00000000..9d04724a --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SemanticDataTest.php @@ -0,0 +1,491 @@ +<?php + +namespace SMW\Tests; + +use SMW\Tests\Util\SemanticDataValidator; +use SMW\Tests\MwDBaseUnitTestCase; + +use SMW\StoreFactory; +use SMW\Configuration\Configuration; +use SMW\DataValueFactory; +use SMW\SemanticData; +use SMW\DIProperty; +use SMW\DIWikiPage; +use SMW\Subobject; + +use SMWDITime as DITime; + +use Title; + +/** + * @covers \SMW\SemanticData + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SemanticDataTest extends \PHPUnit_Framework_TestCase { + + protected function setUp() { + parent::setUp(); + + // DIProperty::findPropertyTypeID is called during the test + // which itself will access the store and to avoid unnecessary + // DB reads inject a mock + $store = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + StoreFactory::setDefaultStoreForUnitTest( $store ); + } + + protected function tearDown() { + StoreFactory::clear(); + } + + public function testConstructor() { + + $instance = new SemanticData( DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ) ); + + $this->assertInstanceOf( + '\SMW\SemanticData', + $instance + ); + + $this->assertInstanceOf( + 'SMWSemanticData', + $instance + ); + } + + public function testGetPropertyValues() { + + $instance = new SemanticData( DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ) ); + + $this->assertInstanceOf( + 'SMW\DIWikiPage', + $instance->getSubject() + ); + + $this->assertEmpty( + $instance->getPropertyValues( new DIProperty( 'Foo', true ) ) + ); + + $this->assertEmpty( + $instance->getPropertyValues( new DIProperty( 'Foo' ) ) + ); + } + + public function testAddPropertyValue() { + + $instance = new SemanticData( DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ) ); + + $instance->addPropertyValue( + 'addPropertyValue', + DIWikiPage::doUnserialize( 'Foo#0#' ) + ); + + $key = Configuration::getInstance()->get( 'wgContLang' )->getNsText( SMW_NS_PROPERTY ) . ':' . 'addPropertyValue'; + + $expected = array( + 'propertyCount' => 1, + 'propertyLabels' => array( $key ), + 'propertyValues' => array( 'Foo' ) + ); + + $semanticDataValidator = new SemanticDataValidator(); + + $semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance + ); + } + + public function testGetHash() { + + $title = Title::newFromText( __METHOD__ ); + $instance = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + + $instance->addDataValue( + DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Bar' ) + ); + + $subobject = $this->newSubobject( $title ); + + $instance->addPropertyObjectValue( + $subobject->getProperty(), + $subobject->getContainer() + ); + + $this->assertInternalType( + 'string', + $instance->getHash() + ); + } + + public function testGetSubSemanticData() { + + $title = Title::newFromText( __METHOD__ ); + $instance = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + + // Adds only a subobject reference to the container + $subobject = $this->newSubobject( $title ); + + $instance->addPropertyObjectValue( + $subobject->getProperty(), + $subobject->getSemanticData()->getSubject() + ); + + $this->assertNotInstanceOf( + 'SMWContainerSemanticData', + $instance->getSubSemanticData() + ); + + // Adds a complete container + $instance->addPropertyObjectValue( + $subobject->getProperty(), + $subobject->getContainer() + ); + + foreach ( $instance->getSubSemanticData() as $subSemanticData ) { + + $this->assertInstanceOf( + 'SMWContainerSemanticData', + $subSemanticData + ); + } + } + + public function testAddAndRemoveSubSemanticData() { + + $title = Title::newFromText( __METHOD__ ); + $instance = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + + // Adds only a subobject reference to the container + $subobject = $this->newSubobject( $title ); + + $instance->addPropertyObjectValue( + $subobject->getProperty(), + $subobject->getSemanticData()->getSubject() + ); + + $this->assertNotInstanceOf( + 'SMWContainerSemanticData', + $instance->getSubSemanticData() + ); + + $instance->addSubSemanticData( $subobject->getSemanticData() ); + + foreach ( $instance->getSubSemanticData() as $subSemanticData ) { + + $this->assertInstanceOf( + 'SMWContainerSemanticData', + $subSemanticData + ); + + $this->assertEquals( + $subSemanticData, + $subobject->getSemanticData() + ); + } + + $instance->removeSubSemanticData( $subobject->getSemanticData() ); + + $this->assertNotInstanceOf( + 'SMWContainerSemanticData', + $instance->getSubSemanticData() + ); + } + + public function testAddSubSemanticDataWithOutSubobjectNameThrowsException() { + + $instance = new SemanticData( DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ) ); + + $this->setExpectedException( 'MWException' ); + + $instance->addSubSemanticData( + new SemanticData( DIWikiPage::newFromTitle( Title::newFromText( 'addSubSemanticData' ) ) ) + ); + } + + public function testAddSubSemanticDataWithDifferentSubSemanticDataIdThrowsException() { + + $instance = new SemanticData( DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ) ); + + $this->setExpectedException( 'MWException' ); + + $instance->addSubSemanticData( + $this->newSubobject( Title::newFromText( 'addSubSemanticData' ) )->getSemanticData() + ); + } + + public function testImportDataFromWithDifferentSubjectThrowsException() { + + $instance = new SemanticData( DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ) ); + + $this->setExpectedException( 'MWException' ); + + $instance->importDataFrom( + new SemanticData( DIWikiPage::newFromTitle( Title::newFromText( 'importDataFrom' ) ) ) + ); + } + + public function testHasAndFindSubSemanticData() { + + $title = Title::newFromText( __METHOD__ ); + $instance = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + + $subobject = $this->newSubobject( $title ); + $subobjectName = $subobject->getSemanticData()->getSubject()->getSubobjectName(); + + $this->assertFalse( $instance->hasSubSemanticData() ); + $this->assertEmpty( $instance->findSubSemanticData( $subobjectName )); + + // Adds only a subobject reference to the container + $instance->addPropertyObjectValue( + $subobject->getProperty(), + $subobject->getSemanticData()->getSubject() + ); + + $this->assertFalse( $instance->hasSubSemanticData( $subobjectName ) ); + $this->assertEmpty( $instance->findSubSemanticData( $subobjectName ) ); + + $instance->addSubSemanticData( $subobject->getSemanticData() ); + + $this->assertTrue( $instance->hasSubSemanticData( $subobjectName ) ); + $this->assertNotEmpty($instance->findSubSemanticData( $subobjectName ) ); + + $this->assertInstanceOf( + 'SMWContainerSemanticData', + $instance->findSubSemanticData( $subobjectName ) + ); + } + + public function testSubSemanticDataOnNonStringSubobjectName() { + + $instance = new SemanticData( DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ) ); + + $this->assertFalse( $instance->hasSubSemanticData( new \stdClass ) ); + $this->assertEmpty( $instance->findSubSemanticData( new \stdClass ) ); + } + + public function testVisibility() { + + $title = Title::newFromText( __METHOD__ ); + $instance = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + + $instance->addDataValue( + DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Bar' ) + ); + + $this->assertTrue( $instance->hasVisibleProperties() ); + + $subobject = $this->newSubobject( $title ); + + $instance->addPropertyObjectValue( + $subobject->getProperty(), + $subobject->getContainer() + ); + + $this->assertTrue( $instance->hasVisibleSpecialProperties() ); + } + + /** + * @dataProvider removePropertyObjectProvider + */ + public function testRemovePropertyObjectValue( $title, $property, $dataItem ) { + + $instance = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + + $instance->addPropertyObjectValue( $property, $dataItem ); + $this->assertFalse( $instance->isEmpty() ); + + $instance->removePropertyObjectValue( $property, $dataItem ); + $this->assertTrue( $instance->isEmpty() ); + } + + public function testClear() { + + $title = Title::newFromText( __METHOD__ ); + $instance = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + + $instance->addPropertyObjectValue( + new DIProperty( '_MDAT' ), + DITime::newFromTimestamp( 1272508903 ) + ); + + $this->assertFalse( $instance->isEmpty() ); + + $instance->clear(); + $this->assertTrue( $instance->isEmpty() ); + } + + /** + * @dataProvider dataValueDataProvider + */ + public function testAddDataValues( $dataValues, $expected ) { + + $title = Title::newFromText( __METHOD__ ); + $instance = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + + foreach ( $dataValues as $dataValue ) { + $instance->addDataValue( $dataValue ); + } + + if ( $expected['error'] > 0 ) { + return $this->assertCount( $expected['error'], $instance->getErrors() ); + } + + $semanticDataValidator = new SemanticDataValidator(); + + $semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance + ); + } + + /** + * @return array + */ + public function removePropertyObjectProvider() { + + $provider = array(); + + $title = Title::newFromText( __METHOD__ ); + $subobject = $this->newSubobject( $title, __METHOD__, '999' ); + + // #0 + $provider[] = array( + $title, + new DIProperty( '_MDAT'), + DITime::newFromTimestamp( 1272508903 ) + ); + + // #1 + $provider[] = array( + $title, + $subobject->getProperty(), + $subobject->getContainer() + ); + + return $provider; + } + + /** + * @return array + */ + public function dataValueDataProvider() { + + $provider = array(); + + // #0 Single DataValue is added + $provider[] = array( + array( + DataValueFactory::getInstance()->newPropertyValue( 'Foo', 'Bar' ), + ), + array( + 'error' => 0, + 'propertyCount' => 1, + 'propertyLabels' => 'Foo', + 'propertyValues' => 'Bar' + ) + ); + + // #1 Equal Datavalues will only result in one added object + $provider[] = array( + array( + DataValueFactory::getInstance()->newPropertyValue( 'Foo', 'Bar' ), + DataValueFactory::getInstance()->newPropertyValue( 'Foo', 'Bar' ), + ), + array( + 'error' => 0, + 'propertyCount' => 1, + 'propertyLabels' => 'Foo', + 'propertyValues' => 'Bar' + ) + ); + + // #2 Two different DataValue objects + $provider[] = array( + array( + DataValueFactory::getInstance()->newPropertyValue( 'Foo', 'Bar' ), + DataValueFactory::getInstance()->newPropertyValue( 'Lila', 'Lula' ), + ), + array( + 'error' => 0, + 'propertyCount' => 2, + 'propertyLabels' => array( 'Foo', 'Lila' ), + 'propertyValues' => array( 'Bar', 'Lula' ) + ) + ); + + // #3 Error (Inverse) + $provider[] = array( + array( + DataValueFactory::getInstance()->newPropertyValue( '-Foo', 'Bar' ), + ), + array( + 'error' => 1, + 'propertyCount' => 0, + ) + ); + + // #4 One valid DataValue + an error object + $provider[] = array( + array( + DataValueFactory::getInstance()->newPropertyValue( 'Foo', 'Bar' ), + DataValueFactory::getInstance()->newPropertyValue( '-Foo', 'bar' ), + ), + array( + 'error' => 1, + 'propertyCount' => 1, + 'propertyLabels' => array( 'Foo' ), + 'propertyValues' => array( 'Bar' ) + ) + ); + + + // #5 Error (Predefined) + $provider[] = array( + array( + DataValueFactory::getInstance()->newPropertyValue( '_Foo', 'Bar' ), + ), + array( + 'error' => 1, + 'propertyCount' => 0, + ) + ); + + // #6 Error (Known predefined property) + $provider[] = array( + array( + DataValueFactory::getInstance()->newPropertyValue( 'Modification date', 'Bar' ), + ), + array( + 'error' => 1, + 'propertyCount' => 0, + ) + ); + + return $provider; + } + + private function newSubobject( Title $title, $property = 'Quuy', $value = 'Xeer' ) { + + $subobject = new Subobject( $title ); + $subobject->setEmptySemanticDataForId( 'Foo' ); + + $subobject->addDataValue( + DataValueFactory::getInstance()->newPropertyValue( $property, $value ) + ); + + return $subobject; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SettingsTest.php b/SemanticMediaWiki/tests/phpunit/includes/SettingsTest.php new file mode 100644 index 00000000..8cef3872 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SettingsTest.php @@ -0,0 +1,209 @@ +<?php + +namespace SMW\Test; + +use SMW\Settings; + +/** + * @covers \SMW\Settings + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class SettingsTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\Settings'; + } + + /** + * @since 1.9 + * + * @return Settings + */ + private function newInstance( array $settings ) { + return Settings::newFromArray( $settings ); + } + + /** + * @dataProvider settingsProvider + * + * @since 1.9 + */ + public function testConstructor( array $settings ) { + + $instance = $this->newInstance( $settings ); + + $this->assertInstanceOf( $this->getClass(), $instance ); + $this->assertFalse( $instance === $this->newInstance( $settings ) ); + + } + + /** + * @dataProvider settingsProvider + * + * @since 1.9 + */ + public function testGet( array $settings ) { + + $instance = $this->newInstance( $settings ); + + foreach ( $settings as $name => $value ) { + $this->assertEquals( $value, $instance->get( $name ) ); + } + + $this->assertTrue( true ); + + } + + /** + * @since 1.9 + */ + public function testInvalidSettingsArgumentException() { + + $this->setExpectedException( '\SMW\InvalidSettingsArgumentException' ); + + $instance = $this->newInstance( array( 'Foo' => 'bar' ) ); + $this->assertEquals( 'bar', $instance->get( 'foo' ) ); + } + + /** + * @dataProvider settingsProvider + * + * @since 1.9 + */ + public function testSet( array $settings ) { + + $instance = $this->newInstance( array() ); + + foreach ( $settings as $name => $value ) { + $instance->set( $name, $value ); + $this->assertEquals( $value, $instance->get( $name ) ); + } + + $this->assertTrue( true ); + + } + + /** + * @dataProvider globalsSettingsProvider + * + * @since 1.9 + */ + public function testNewFromGlobals( array $settings ) { + + $instance = Settings::newFromGlobals(); + $this->assertInstanceOf( $this->getClass(), $instance ); + + // Assert that newFromGlobals is a static instance + $this->assertTrue( $instance === Settings::newFromGlobals() ); + + // Reset instance + $instance->clear(); + $this->assertTrue( $instance !== Settings::newFromGlobals() ); + + foreach ( $settings as $key => $value ) { + $this->assertTrue( $instance->has( $key ), "Failed asserting that {$key} exists" ); + } + } + + /** + * @dataProvider nestedSettingsProvider + * + * @since 1.9 + */ + public function testNestedSettingsIteration( $test, $key, $expected ) { + + $instance = $this->newInstance( $test ); + + $this->assertInternalType( $expected['type'], $instance->get( $key ) ); + $this->assertEquals( $expected['value'], $instance->get( $key ) ); + + } + + /** + * Provides sample data to be tested + * + * @par Example: + * @code + * array( + * 'Foo' => $this->newRandomString(), + * 'Bar' => array( + * 'Lula' => $this->newRandomString(), + * 'Lila' => array( + * 'Lala' => $this->newRandomString(), + * 'parent' => array( + * 'child' => array( 'Lisa', 'Lula', array( 'Lila' ) ) + * ) + * ) + * ) + * ) + * @endcode + * + * @return array + */ + public function nestedSettingsProvider() { + + $Foo = $this->newRandomString(); + $Lula = $this->newRandomString(); + $Lala = $this->newRandomString(); + + $child = array( 'Lisa', 'Lula', array( 'Lila' ) ); + $parent = array( 'child' => $child ); + + $Lila = array( 'Lala' => $Lala, 'parent' => $parent ); + $Bar = array( 'Lula' => $Lula, 'Lila' => $Lila ); + $test = array( 'Foo' => $Foo, 'Bar' => $Bar ); + + return array( + array( $test, 'Foo', array( 'type' => 'string', 'value' => $Foo ) ), + array( $test, 'Bar', array( 'type' => 'array', 'value' => $Bar ) ), + array( $test, 'Lula', array( 'type' => 'string', 'value' => $Lula ) ), + array( $test, 'Lila', array( 'type' => 'array', 'value' => $Lila ) ), + array( $test, 'Lala', array( 'type' => 'string', 'value' => $Lala ) ), + array( $test, 'parent', array( 'type' => 'array', 'value' => $parent ) ), + array( $test, 'child', array( 'type' => 'array', 'value' => $child ) ) + ); + } + + /** + * Provides sample data to be tested + * + * @return array + */ + public function settingsProvider() { + return array( array( array( + 'foo' => 'bar', + 'baz' => 'BAH', + 'bar' => array( '9001' ), + 'foo' => array( '9001', array( 9001, 4.2 ) ), + '~[,,_,,]:3' => array( 9001, 4.2 ), + ) ) ); + } + + /** + * Provides and collects individual smwg* settings + * + * @return array + */ + public function globalsSettingsProvider() { + + $settings = array_intersect_key( $GLOBALS, + array_flip( preg_grep('/^smwg/', array_keys( $GLOBALS ) ) ) + ); + + return array( array( $settings ) ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SetupTest.php b/SemanticMediaWiki/tests/phpunit/includes/SetupTest.php new file mode 100644 index 00000000..9fc5814c --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SetupTest.php @@ -0,0 +1,635 @@ +<?php + +namespace SMW\Test; + +use SMW\Setup; +use SMW\ExtensionContext; + +/** + * @covers \SMW\Setup + * + * @group SMW + * @group SMWExtension + * @group medium + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SetupTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\Setup'; + } + + /** + * @since 1.9 + */ + private function newExtensionContext( $store = null ) { + + $context = new ExtensionContext(); + + $settings = $context->getSettings(); + $settings->set( 'smwgCacheType', CACHE_NONE ); + $settings->set( 'smwgEnableUpdateJobs', false ); + + $context->getDependencyBuilder() + ->getContainer() + ->registerObject( 'Store', $this->newMockBuilder()->newObject( 'Store' ) ); + + return $context; + } + + /** + * @since 1.9 + * + * @return Setup + */ + private function newInstance( &$config = array(), $basePath = 'Foo', $context = null ) { + + $language = $this->newMockBuilder()->newObject( 'Language' ); + + $default = array( + 'smwgNamespacesWithSemanticLinks' => array(), + 'smwgEnableUpdateJobs' => false, + 'wgNamespacesWithSubpages' => array(), + 'wgExtensionAssetsPath' => false, + 'wgResourceModules' => array(), + 'wgScriptPath' => '/Foo', + 'wgServer' => 'http://example.org', + 'wgVersion' => '1.21', + 'wgLanguageCode' => 'en', + 'wgLang' => $language, + 'IP' => 'Foo' + ); + + $config = array_merge( $default, $config ); + + if( $context === null ) { + $context = $this->newExtensionContext(); + } + + return new Setup( $config, $basePath, $context ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testResourceModules() { + + $config = array(); + $context = $this->newExtensionContext(); + $basepath = $context->getSettings()->get( 'smwgIP' ); + + $this->newInstance( $config, $basepath, $context )->run(); + $this->assertNotEmpty( $config['wgResourceModules'] ); + + } + + /** + * @dataProvider functionHooksProvider + * + * @since 1.9 + */ + public function testRegisterFunctionHooksWithoutInitialization( $hook, $setup ) { + $this->assertArrayHookEntry( $hook, $setup, 1 ); + } + + /** + * @dataProvider functionHookForInitializationProvider + * + * @since 1.9 + */ + public function testRegisterFunctionHookWithInitialization( $hook, $setup ) { + + $this->assertArrayHookEntry( $hook, $setup, 1 ); + + // Verify that registered closures are executable + $result = $this->executeHookOnMock( $hook, $setup['wgHooks'][$hook][0] ); + + if ( $result !== null ) { + $this->assertTrue( $result ); + } else { + $this->markTestIncomplete( "Test is incomplete because of a missing {$hook} closure verification" ); + } + + } + + /** + * @dataProvider parserHooksForInitializationProvider + * + * @since 1.9 + */ + public function testParserHooksWithInitialization( $hook, $setup ) { + + // 4 because of having hooks registered without using a callback, after + // all parser hooks being registered using a callback this can be + // reduced to 1 + $this->assertArrayHookEntry( $hook, $setup, 3 ); + + // Verify that registered closures are executable + $result = $this->executeHookOnMock( $hook, $setup['wgHooks'][$hook][0] ); + + if ( $result !== null ) { + $this->assertTrue( $result ); + } else { + $this->markTestIncomplete( "Test is incomplete because of a missing {$hook} closure verification" ); + } + + } + + /** + * Verifies that a registered closure can be executed + * + * @since 1.9 + */ + private function executeHookOnMock( $hook, $object ) { + + $empty = ''; + $emptyArray = array(); + + $editInfo = (object)array(); + $editInfo->output = null; + + // Evade execution by setting the title object as isSpecialPage + // the hook class should always ensure that isSpecialPage is checked + $title = $this->newMockBuilder()->newObject( 'Title', array( + 'isSpecialPage' => true + ) ); + + $user = $this->getMockBuilder( '\User' ) + ->disableOriginalConstructor() + ->getMock(); + + $user->expects( $this->any() ) + ->method( 'isAllowed' ) + ->will( $this->returnValue( false ) ); + + $parserOutput = $this->newMockBuilder()->newObject( 'ParserOutput' ); + + $outputPage = $this->newMockBuilder()->newObject( 'OutputPage', array( + 'getTitle' => $title + ) ); + + $parser = $this->newMockBuilder()->newObject( 'Parser', array( + 'getTitle' => $title + ) ); + + $linksUpdate = $this->newMockBuilder()->newObject( 'LinksUpdate', array( + 'getTitle' => $title, + 'getParserOutput' => $parserOutput + ) ); + + $skin = $this->newMockBuilder()->newObject( 'Skin', array( + 'getTitle' => $title, + 'getOutput' => $outputPage + ) ); + + $skinTemplate = $this->getMockBuilder( '\SkinTemplate' ) + ->disableOriginalConstructor() + ->getMock(); + + $skinTemplate->expects( $this->any() ) + ->method( 'getSkin' ) + ->will( $this->returnValue( $skin ) ); + + $skinTemplate->expects( $this->any() ) + ->method( 'getUser' ) + ->will( $this->returnValue( $user ) ); + + $parserOptions = $this->newMockBuilder()->newObject( 'ParserOptions' ); + + $file = $this->newMockBuilder()->newObject( 'File', array( + 'getTitle' => null + ) ); + + $wikiPage = $this->newMockBuilder()->newObject( 'WikiPage', array( + 'prepareContentForEdit' => $editInfo, + 'prepareTextForEdit' => $editInfo, + 'getTitle' => $title, + ) ); + + $revision = $this->newMockBuilder()->newObject( 'Revision', array( + 'getTitle' => $title, + 'getRawText' => 'Foo', + 'getContent' => $this->newMockContent() + ) ); + + $databaseUpdater = $this->getMockBuilder( '\DatabaseUpdater' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $resourceLoader = $this->getMockBuilder( '\ResourceLoader' ) + ->disableOriginalConstructor() + ->getMock(); + + switch ( $hook ) { + case 'SkinAfterContent': + $result = $this->callObject( $object, array( &$empty, $skin ) ); + break; + case 'OutputPageParserOutput': + $result = $this->callObject( $object, array( &$outputPage, $parserOutput ) ); + break; + case 'BeforePageDisplay': + $result = $this->callObject( $object, array( &$outputPage, &$skin ) ); + break; + case 'InternalParseBeforeLinks': + $result = $this->callObject( $object, array( &$parser, &$empty ) ); + break; + case 'ParserAfterTidy': + $result = $this->callObject( $object, array( &$parser, &$empty ) ); + break; + case 'LinksUpdateConstructed': + $result = $this->callObject( $object, array( $linksUpdate ) ); + break; + case 'BaseTemplateToolbox': + $result = $this->callObject( $object, array( $skinTemplate, &$empty ) ); + break; + case 'NewRevisionFromEditComplete': + $result = $this->callObject( $object, array( $wikiPage, $revision, $empty, $user ) ); + break; + case 'TitleMoveComplete': + $result = $this->callObject( $object, array( &$title, &$title, &$user, $empty, $empty ) ); + break; + case 'CanonicalNamespaces': + $result = $this->callObject( $object, array( &$emptyArray ) ); + break; + case 'ArticlePurge': + $result = $this->callObject( $object, array( &$wikiPage ) ); + break; + case 'ArticleDelete': + $result = $this->callObject( $object, array( &$wikiPage, &$user, &$empty, &$empty ) ); + break; + case 'SpecialStatsAddExtra': + $result = $this->callObject( $object, array( &$emptyArray ) ); + break; + case 'FileUpload': + $result = $this->callObject( $object, array( $file, $empty ) ); + break; + case 'ResourceLoaderGetConfigVars': + $result = $this->callObject( $object, array( &$emptyArray ) ); + break; + case 'GetPreferences': + $result = $this->callObject( $object, array( $user, &$emptyArray ) ); + break; + case 'SkinTemplateNavigation': + $result = $this->callObject( $object, array( &$skinTemplate, &$emptyArray ) ); + break; + case 'LoadExtensionSchemaUpdates': + $result = $this->callObject( $object, array( $databaseUpdater ) ); + break; + case 'ResourceLoaderTestModules': + $result = $this->callObject( $object, array( &$emptyArray, &$resourceLoader ) ); + break; + case 'ExtensionTypes': + $result = $this->callObject( $object, array( &$emptyArray ) ); + break; + case 'TitleIsAlwaysKnown': + $result = $this->callObject( $object, array( $title, &$empty ) ); + break; + case 'BeforeDisplayNoArticleText': + $result = $this->callObject( $object, array( $wikiPage ) ); + break; + case 'ArticleFromTitle': + $result = $this->callObject( $object, array( &$title, &$wikiPage ) ); + break; + case 'ParserFirstCallInit': + + // ParserFirstCallInit itself contains closures for + // registered parser functions that are not checked here + // @see ParserFunctionIntegrationTest + + $result = $this->callObject( $object, array( &$parser ) ); + break; + default: + $result = null; + } + + return $result; + } + + /** + * @since 1.9 + * + * @return boolean + */ + private function callObject( $object, array $arguments ) { + return is_callable( $object ) ? call_user_func_array( $object, $arguments ) : false; + } + + /** + * @dataProvider apiModulesDataProvider + * + * @since 1.9 + */ + public function testRegisterApiModules( $moduleEntry, $setup ) { + $this->assertArrayEntryExists( 'wgAPIModules', $moduleEntry, $setup ); + } + + /** + * @dataProvider jobClassesDataProvider + * + * @since 1.9 + */ + public function testRegisterJobClasses( $jobEntry, $setup ) { + $this->assertArrayEntryExists( 'wgJobClasses', $jobEntry, $setup ); + } + + /** + * @dataProvider messagesFilesDataProvider + * + * @since 1.9 + */ + public function testRegisterMessageFiles( $moduleEntry, $setup ) { + $this->assertArrayEntryExists( 'wgExtensionMessagesFiles', $moduleEntry, $setup, 'file' ); + } + + /** + * @dataProvider specialPageDataProvider + * + * @since 1.9 + */ + public function testRegisterSpecialPages( $specialEntry, $setup ) { + $this->assertArrayEntryExists( 'wgSpecialPages', $specialEntry, $setup ); + } + + /** + * @since 1.9 + */ + public function testRegisterRights() { + + $setup['wgAvailableRights'][] = ''; + $setup['wgGroupPermissions']['sysop']['smw-admin'] = ''; + $setup['wgGroupPermissions']['smwadministrator']['smw-admin'] = ''; + + foreach ( $setup['wgAvailableRights'] as $value ) { + $this->assertEmpty( $value ); + } + + $this->assertEmpty( $setup['wgGroupPermissions']['sysop']['smw-admin'] ); + $this->assertEmpty( $setup['wgGroupPermissions']['smwadministrator']['smw-admin'] ); + + $this->newInstance( $setup )->run(); + + $this->assertNotEmpty( $setup['wgAvailableRights'] ); + $this->assertNotEmpty( $setup['wgGroupPermissions']['sysop']['smw-admin'] ); + $this->assertNotEmpty( $setup['wgGroupPermissions']['smwadministrator']['smw-admin'] ); + + } + + /** + * @since 1.9 + */ + public function testRegisterParamDefinitions() { + + $setup['wgParamDefinitions']['smwformat'] = ''; + + $this->assertEmpty( $setup['wgParamDefinitions']['smwformat'] ); + + $this->newInstance( $setup )->run(); + + $this->assertNotEmpty( $setup['wgParamDefinitions']['smwformat'] ); + + } + + /** + * @since 1.9 + */ + public function testRegisterFooterIcon() { + + $setup['wgFooterIcons']['poweredby']['semanticmediawiki'] = ''; + + $this->newInstance( $setup )->run(); + $this->assertNotEmpty( $setup['wgFooterIcons']['poweredby']['semanticmediawiki'] ); + + } + + /** + * @return array + */ + public function specialPageDataProvider() { + + $specials = array( + 'Ask', + 'Browse', + 'PageProperty', + 'SearchByProperty', + 'SMWAdmin', + 'SemanticStatistics', + 'Concepts', + 'ExportRDF', + 'Types', + 'URIResolver', + 'Properties', + 'UnusedProperties', + 'WantedProperties', + ); + + return $this->buildDataProvider( 'wgSpecialPages', $specials, '' ); + } + + /** + * @return array + */ + public function jobClassesDataProvider() { + + $jobs = array( + 'SMW\UpdateJob', + 'SMW\RefreshJob', + 'SMW\UpdateDispatcherJob', + 'SMW\DeleteSubjectJob', + + // Legacy + 'SMWUpdateJob', + 'SMWRefreshJob', + ); + + return $this->buildDataProvider( 'wgJobClasses', $jobs, '' ); + } + + /** + * @return array + */ + public function apiModulesDataProvider() { + + $modules = array( + 'ask', + 'smwinfo', + 'askargs', + 'browsebysubject', + ); + + return $this->buildDataProvider( 'wgAPIModules', $modules, '' ); + } + + + /** + * @return array + */ + public function messagesFilesDataProvider() { + + $modules = array( + 'SemanticMediaWiki', + 'SemanticMediaWikiAlias', + 'SemanticMediaWikiMagic', + 'SemanticMediaWikiNamespaces' + ); + + return $this->buildDataProvider( 'wgExtensionMessagesFiles', $modules, '' ); + } + + /** + * @return array + */ + public function functionHooksProvider() { + + $hooks = array( + 'AdminLinks', + 'PageSchemasRegisterHandlers', + ); + + return $this->buildDataProvider( 'wgHooks', $hooks, array() ); + } + + /** + * @return array + */ + public function functionHookForInitializationProvider() { + + $hooks = array( + 'SkinAfterContent', + 'OutputPageParserOutput', + 'BeforePageDisplay', + 'InternalParseBeforeLinks', + 'TitleMoveComplete', + 'NewRevisionFromEditComplete', + 'ArticlePurge', + 'ArticleDelete', + 'ParserAfterTidy', + 'LinksUpdateConstructed', + 'SpecialStatsAddExtra', + 'BaseTemplateToolbox', + 'CanonicalNamespaces', + 'FileUpload', + 'ResourceLoaderGetConfigVars', + 'GetPreferences', + 'SkinTemplateNavigation', + 'LoadExtensionSchemaUpdates', + 'ResourceLoaderTestModules', + 'ExtensionTypes', + 'TitleIsAlwaysKnown', + 'BeforeDisplayNoArticleText', + 'ArticleFromTitle', + ); + + return $this->buildDataProvider( 'wgHooks', $hooks, array() ); + } + + /** + * @return array + */ + public function parserHooksForInitializationProvider() { + + $hooks = array( + 'ParserFirstCallInit' + ); + + return $this->buildDataProvider( 'wgHooks', $hooks, array() ); + } + + /** + * @since 1.9 + */ + private function assertArrayHookEntry( $hook, &$setup, $expectedCount ) { + + $this->assertCount( + 0, + $setup['wgHooks'][$hook], + 'Asserts that before run() the entry counts 0' + ); + + $this->newInstance( $setup )->run(); + + $this->assertCount( + $expectedCount, + $setup['wgHooks'][$hook], + "Asserts that after run() the entry counts {$expectedCount}" + ); + + } + + /** + * @since 1.9 + */ + private function assertArrayEntryExists( $target, $entry, $setup, $type = 'class' ) { + + $this->assertEmpty( + $setup[$target][$entry], + "Asserts that {$entry} is empty" + ); + + $this->newInstance( $setup )->run(); + + $this->assertNotEmpty( $setup[$target][$entry] ); + + switch ( $type ) { + case 'class': + $this->assertTrue( class_exists( $setup[$target][$entry] ) ); + break; + case 'file': + $this->assertTrue( file_exists( $setup[$target][$entry] ) ); + break; + } + + } + + /** + * @return array + */ + private function buildDataProvider( $id, $definitions, $default ) { + + $provider = array(); + + foreach ( $definitions as $definition ) { + $provider[] = array( + $definition, + array( $id => array( $definition => $default ) ), + ); + } + + return $provider; + } + + /** + * @return Content|null + */ + public function newMockContent() { + + $content = null; + + if ( class_exists( 'ContentHandler' ) ) { + + $contentHandler = $this->newMockBuilder()->newObject( 'ContentHandler', array( + 'getDefaultFormat' => 'Foo' + ) ); + + $content = $this->newMockBuilder()->newObject( 'Content', array( + 'getContentHandler' => $contentHandler, + ) ); + } + + return $content; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SimpleDictionaryTest.php b/SemanticMediaWiki/tests/phpunit/includes/SimpleDictionaryTest.php new file mode 100644 index 00000000..dee462bf --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SimpleDictionaryTest.php @@ -0,0 +1,267 @@ +<?php + +namespace SMW\Test; + +use SMW\SimpleDictionary; + +/** + * @covers \SMW\SimpleDictionary + * @covers \SMW\ObjectStorage + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SimpleDictionaryTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\SimpleDictionary'; + } + + /** + * @since 1.9 + * + * @return SimpleDictionary + */ + private function newInstance( array $chapter = array() ) { + return new SimpleDictionary( $chapter ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testInvalidArgumentExceptionHas() { + + $this->setExpectedException( 'InvalidArgumentException' ); + $this->assertInternalType( 'string', $this->newInstance()->has( 9001 ) ); + } + + /** + * @since 1.9 + */ + public function testInvalidArgumentExceptionSet() { + + $this->setExpectedException( 'InvalidArgumentException' ); + $this->assertInternalType( 'string', $this->newInstance()->set( 9001, 'lila' ) ); + } + + /** + * @since 1.9 + */ + public function testInvalidArgumentExceptionRemove() { + + $this->setExpectedException( 'InvalidArgumentException' ); + $this->assertInternalType( 'string', $this->newInstance()->remove( 9001 ) ); + } + + /** + * @since 1.9 + */ + public function testOutOfBoundsException() { + + $this->setExpectedException( 'OutOfBoundsException' ); + $this->assertInternalType( 'string', $this->newInstance()->get( 'lala' ) ); + } + + /** + * @dataProvider arrayDataProvider + * + * @since 1.9 + */ + public function testRoundTrip( $setup, $expected ) { + + $newValue = $this->newRandomString(); + $instance = $this->newInstance( $setup['array'] ); + + // Get + $this->assertInternalType( $expected['type'], $instance->get( $setup['key'] ) ); + + // toArray + $this->assertEquals( $expected['result'], $instance->toArray() ); + + // Set + $instance->set( $setup['key'], $newValue ); + $this->assertEquals( $newValue, $instance->get( $setup['key'] ) ); + + // Remove + $instance->remove( $setup['key'] ); + + $this->assertFalse( + $instance->has( $setup['key'] ), + 'asserts that detach/removal will result alwasy in false' + ); + + $instance->remove( $setup['key'] ); + + $this->assertFalse( + $instance->has( $setup['key'] ), + 'asserts that detach/removal will result alwasy in false' + ); + + } + + /** + * @since 1.9 + */ + public function testMerge() { + + $SimpleDictionary = $this->newInstance( array( 'lila' => 'lila' ) ); + $this->assertEquals( 'lila' , $SimpleDictionary->get( 'lila' ) ); + + $mergeable = $this->newInstance( array( 'lila' => array( 'lula', 9001 ) ) ); + $this->assertEquals( array( 'lula', 9001 ), $mergeable->get( 'lila' ) ); + + $SimpleDictionary->merge( $mergeable->toArray() ); + $this->assertEquals( array( 'lula', 9001 ), $SimpleDictionary->get( 'lila' ) ); + + } + + /* + * @since 1.9 + public function testRuntimeComparison() { + + echo "\n"; + + $counter = 1; + $s = array(); + $time = microtime( true ); + + for( $x = 0; $x < $counter; $x++ ) { + $s[] = array( "name"=>"Adam", "age"=> 35 ); + }; + + echo 'N-Array, Memory: ' . memory_get_peak_usage() . ' Execution time: ' . ( microtime( true ) - $time ) . "\n"; + unset( $s ); + $time = microtime( true ); + + $s = array(); + $h = $this->newInstance(); + + for( $x = 0; $x < $counter; $x++ ) { + $h->set( "name", "Adam" )->set( "age", 35 ); + $s[] = $h->toArray(); + }; + + echo 'H-Array, Memory: ' . memory_get_peak_usage() . ' Execution time: ' . ( microtime( true ) - $time ) . "\n"; + unset( $s ); + $time = microtime( true ); + + $s = array(); + $o = new \ArrayObject; + + for( $x = 0; $x < $counter; $x++ ) { + $o->offsetSet( "name", "Adam" ); + $o->offsetSet( "age", 35 ); + $s[] = $o->getArrayCopy(); + }; + + echo 'O-Array, Memory: ' . memory_get_peak_usage() . ' Execution time: ' . ( microtime( true ) - $time ) . "\n"; + + $this->assertTrue( true ); + + } + */ + + /** + * @return array + */ + public function arrayDataProvider() { + + $provider = array(); + + // #0 string + $key = $this->newRandomString(); + $test = array( $key => $this->newRandomString() ); + + $provider[] = array( + array( + 'key' => $key, + 'array' => $test + ), + array( + 'type' => 'string', + 'result' => $test + ) + ); + + // #1 array + $key = $this->newRandomString(); + $new = array( rand( 10, 200 ), array( $this->newRandomString() ) ); + $test = array( $key => array_merge( $test, $new ) ); + + $provider[] = array( + array( + 'key' => $key, + 'array' => $test + ), + array( + 'type' => 'array', + 'result' => $test + ) + ); + + // #2 null + $key = $this->newRandomString(); + $test = array( $key => null ); + + $provider[] = array( + array( + 'key' => $key, + 'array' => $test + ), + array( + 'type' => 'null', + 'result' => $test + ) + ); + + // #3 array() + $key = $this->newRandomString(); + $test = array( $key => array() ); + + $provider[] = array( + array( + 'key' => $key, + 'array' => $test + ), + array( + 'type' => 'array', + 'result' => $test + ) + ); + + // #4 objects + $key = $this->newRandomString(); + $test = array( $key => array( new SimpleDictionary( array( 'Foo' => 'Bar' ) ), new SimpleDictionary() ) ); + + $provider[] = array( + array( + 'key' => $key, + 'array' => $test + ), + array( + 'type' => 'array', + 'result' => $test + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/Store/Maintenance/ConceptCacheRebuilderTest.php b/SemanticMediaWiki/tests/phpunit/includes/Store/Maintenance/ConceptCacheRebuilderTest.php new file mode 100644 index 00000000..fbb8a4f7 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Store/Maintenance/ConceptCacheRebuilderTest.php @@ -0,0 +1,230 @@ +<?php + +namespace SMW\Tests\Store\Maintenance; + +use SMW\Store\Maintenance\ConceptCacheRebuilder; +use SMW\DIConcept; + +/** + * @uses \SMW\Store\Maintenance\ConceptCacheRebuilder + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-unit + * @group mediawiki-databaseless + * + * @license GNU GPL v2+ + * @since 1.9.2 + * + * @author mwjames + */ +class ConceptCacheRebuilderTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $store = $this->getMockForAbstractClass( '\SMW\Store' ); + + $settings = $this->getMockBuilder( '\SMW\Settings' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\Store\Maintenance\ConceptCacheRebuilder', + new ConceptCacheRebuilder( $store, $settings ) + ); + } + + /** + * @depends testCanConstruct + */ + public function testRebuildWithoutOptionsAndActions() { + + $store = $this->getMockForAbstractClass( '\SMW\Store' ); + + $settings = $this->getMockBuilder( '\SMW\Settings' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new ConceptCacheRebuilder( + $store, + $settings + ); + + $this->assertFalse( $instance->rebuild() ); + } + + /** + * @dataProvider actionProvider + */ + public function testRebuildFullConceptWithoutRangeSelectionOnMockStore( $action ) { + + $concept = new DIConcept( 'Foo', '', '', '', '' ); + + $concept->setCacheStatus( 'full' ); + $concept->setCacheDate( '1358515326' ) ; + $concept->setCacheCount( '1000' ); + + $instance = $this->acquireInstanceFor( $concept ); + + $instance->setParameters( array( + $action => true + ) ); + + $this->assertTrue( $instance->rebuild() ); + } + + /** + * @dataProvider actionProvider + */ + public function testRebuildEmptyConceptWithoutRangeSelectionOnMockStore( $action ) { + + $concept = new DIConcept( 'Foo', '', '', '', '' ); + $concept->setCacheStatus( 'empty' ); + + $instance = $this->acquireInstanceFor( $concept ); + + $instance->setParameters( array( + $action => true + ) ); + + $this->assertTrue( $instance->rebuild() ); + } + + /** + * @dataProvider actionProvider + */ + public function testRebuildFullConceptWithRangeSelectionOnMockStore( $action ) { + + $concept = new DIConcept( 'Foo', '', '', '', '' ); + + $concept->setCacheStatus( 'full' ); + $concept->setCacheDate( '1358515326' ) ; + $concept->setCacheCount( '1000' ); + + $instance = $this->acquireInstanceFor( $concept ); + + $instance->setParameters( array( + $action => true, + 's' => 0, + 'e' => 90000 + ) ); + + $this->assertTrue( $instance->rebuild() ); + } + + /** + * @dataProvider actionProvider + */ + public function testRebuildSingleEmptyConceptWithRangeSelectionOnMockStore( $action ) { + + $concept = new DIConcept( 'Foo', '', '', '', '' ); + $concept->setCacheStatus( 'empty' ); + + $instance = $this->acquireInstanceFor( $concept ); + + $instance->setParameters( array( + $action => true, + 's' => 0, + 'e' => 90000 + ) ); + + $this->assertTrue( $instance->rebuild() ); + } + + /** + * @dataProvider actionProvider + */ + public function testRebuildSingleFullConceptOnMockStore( $action ) { + + $concept = new DIConcept( 'Foo', '', '', '', '' ); + + $concept->setCacheStatus( 'full' ); + $concept->setCacheDate( '1358515326' ) ; + $concept->setCacheCount( '1000' ); + + $instance = $this->acquireInstanceFor( $concept ); + + $instance->setParameters( array( + $action => true, + 'old' => 10, + 'concept' => 'Bar' + ) ); + + $this->assertTrue( $instance->rebuild() ); + } + + /** + * @dataProvider actionProvider + */ + public function testRebuildWithNullConceptOnMockStore( $action ) { + + $instance = $this->acquireInstanceFor( null ); + + $instance->setParameters( array( + $action => true, + 'concept' => 'Bar' + ) ); + + $this->assertTrue( $instance->rebuild() ); + } + + private function acquireInstanceFor( $concept = null ) { + + $expectedToRun = $concept !== null ? $this->any() : $this->never(); + $refreshConceptCacheReturn = $concept !== null ? $concept->getConceptQuery() : null; + + $row = new \stdClass; + $row->page_namespace = 0; + $row->page_title = 1; + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $expectedToRun ) + ->method( 'select' ) + ->will( $this->returnValue( array( $row ) ) ); + + $store = $this->getMockBuilder( 'SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $store->expects( $this->once() ) + ->method( 'getConceptCacheStatus' ) + ->will( $this->returnValue( $concept ) ); + + $store->expects( $expectedToRun ) + ->method( 'refreshConceptCache' ) + ->will( $this->returnValue( array( $refreshConceptCacheReturn ) ) ); + + $store->expects( $expectedToRun ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $settings = $this->getMockBuilder( '\SMW\Settings' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new ConceptCacheRebuilder( + $store, + $settings + ); + + $instance->setParameters( array( + 'quiet' => true, + ) ); + + return $instance; + } + + public function actionProvider() { + return array( + array( 'status' ), + array( 'create' ), + array( 'delete' ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/Store/Maintenance/DataRebuilderTest.php b/SemanticMediaWiki/tests/phpunit/includes/Store/Maintenance/DataRebuilderTest.php new file mode 100644 index 00000000..69e62c90 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Store/Maintenance/DataRebuilderTest.php @@ -0,0 +1,297 @@ +<?php + +namespace SMW\Tests\Store\Maintenance; + +use SMW\Store\Maintenance\DataRebuilder; + +use Title; + +/** + * @uses \SMW\Store\Maintenance\DataRebuilder + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-unit + * @group mediawiki-databaseless + * + * @license GNU GPL v2+ + * @since 1.9.2 + * + * @author mwjames + */ +class DataRebuilderTest extends \PHPUnit_Framework_TestCase { + + protected $obLevel; + + // The Store writes to the output buffer during drop/setupStore, to avoid + // inappropriate buffer settings which can cause interference during unit + // testing, we clean the output buffer + protected function setUp() { + $this->obLevel = ob_get_level(); + ob_start(); + + parent::setUp(); + } + + protected function tearDown() { + parent::tearDown(); + + while ( ob_get_level() > $this->obLevel ) { + ob_end_clean(); + } + } + + public function testCanConstruct() { + + $store = $this->getMockForAbstractClass( '\SMW\Store' ); + + $this->assertInstanceOf( + '\SMW\Store\Maintenance\DataRebuilder', + new DataRebuilder( $store, null ) + ); + } + + /** + * @depends testCanConstruct + */ + public function testRebuildAllWithoutOptions() { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( 'refreshData' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->once() ) + ->method( 'refreshData' ) + ->will( $this->returnCallback( array( $this, 'refreshDataOnMockCallback' ) ) ); + + $instance = new DataRebuilder( $store, null ); + + // Needs an end otherwise phpunit is caught up in an infinite loop + $instance->setParameters( array( + 'e' => 1 + ) ); + + $this->assertTrue( $instance->rebuild() ); + } + + /** + * @depends testCanConstruct + */ + public function testRebuildAllWithFullDelete() { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( + 'refreshData', + 'drop' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->once() ) + ->method( 'refreshData' ) + ->will( $this->returnCallback( array( $this, 'refreshDataOnMockCallback' ) ) ); + + $store->expects( $this->once() ) + ->method( 'drop' ); + + $instance = new DataRebuilder( $store, null ); + + $instance->setParameters( array( + 'e' => 1, + 'f' => true, + 'verbose' => false + ) ); + + $this->assertTrue( $instance->rebuild() ); + } + + /** + * @depends testCanConstruct + */ + public function testRebuildAllWithStopRangeOption() { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( 'refreshData' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->exactly( 6 ) ) + ->method( 'refreshData' ) + ->will( $this->returnCallback( array( $this, 'refreshDataOnMockCallback' ) ) ); + + $instance = new DataRebuilder( $store, null ); + + $instance->setParameters( array( + 's' => 2, + 'n' => 5, + 'verbose' => false + ) ); + + $this->assertTrue( $instance->rebuild() ); + } + + /** + * @depends testCanConstruct + */ + public function testRebuildSelectedPagesWithQueryOption() { + + $subject = $this->getMockBuilder( '\SMW\DIWikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $subject->expects( $this->once() ) + ->method( 'getTitle' ) + ->will( $this->returnValue( Title::newFromText( __METHOD__ ) ) ); + + $queryResult = $this->getMockBuilder( '\SMWQueryResult' ) + ->disableOriginalConstructor() + ->getMock(); + + $queryResult->expects( $this->once() ) + ->method( 'getResults' ) + ->will( $this->returnValue( array( $subject ) ) ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $store->expects( $this->at( 0 ) ) + ->method( 'getQueryResult' ) + ->will( $this->returnValue( 1 ) ); + + $store->expects( $this->at( 1 ) ) + ->method( 'getQueryResult' ) + ->will( $this->returnValue( $queryResult ) ); + + $instance = new DataRebuilder( $store, null ); + + $instance->setParameters( array( + 'query' => '[[Category:Foo]]' + ) ); + + $this->assertTrue( $instance->rebuild() ); + } + + public function testRebuildSelectedPagesWithCategoryNamespaceFilter() { + + $row = new \stdClass; + $row->cat_title = 'Foo'; + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->any() ) + ->method( 'select' ) + ->with( $this->stringContains( 'category' ), + $this->anything(), + $this->anything(), + $this->anything(), + $this->anything() ) + ->will( $this->returnValue( array( $row ) ) ); + + $store = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->setMethods( array( 'getDatabase' ) ) + ->getMock(); + + $store->expects( $this->once() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $instance = new DataRebuilder( $store, null ); + + $instance->setParameters( array( + 'c' => true + ) ); + + $this->assertTrue( $instance->rebuild() ); + } + + public function testRebuildSelectedPagesWithPropertyNamespaceFilter() { + + $row = new \stdClass; + $row->page_namespace = SMW_NS_PROPERTY; + $row->page_title = 'Bar'; + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->any() ) + ->method( 'select' ) + ->with( $this->anything(), + $this->anything(), + $this->equalTo( array( 'page_namespace' => SMW_NS_PROPERTY ) ), + $this->anything(), + $this->anything() ) + ->will( $this->returnValue( array( $row ) ) ); + + $store = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->setMethods( array( 'getDatabase' ) ) + ->getMock(); + + $store->expects( $this->once() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $instance = new DataRebuilder( $store, null ); + + $instance->setParameters( array( + 'p' => true + ) ); + + $this->assertTrue( $instance->rebuild() ); + } + + public function testRebuildSelectedPagesWithPageOption() { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $instance = $this->getMockBuilder( '\SMW\Store\Maintenance\DataRebuilder' ) + ->setConstructorArgs( array( $store, null ) ) + ->setMethods( array( 'makeTitleOf' ) ) + ->getMock(); + + $instance->expects( $this->at( 0 ) ) + ->method( 'makeTitleOf' ) + ->with( $this->equalTo( 'Main page' ) ) + ->will( $this->returnValue( Title::newFromText( 'Main page' ) ) ); + + $instance->expects( $this->at( 1 ) ) + ->method( 'makeTitleOf' ) + ->with( $this->equalTo( 'Some other page' ) ) + ->will( $this->returnValue( Title::newFromText( 'Some other page' ) ) ); + + $instance->expects( $this->at( 2 ) ) + ->method( 'makeTitleOf' ) + ->with( $this->equalTo( 'Help:Main page' ) ) + ->will( $this->returnValue( Title::newFromText( 'Main page', NS_HELP ) ) ); + + $instance->expects( $this->at( 3 ) ) + ->method( 'makeTitleOf' ) + ->with( $this->equalTo( 'Main page' ) ) + ->will( $this->returnValue( Title::newFromText( 'Main page' ) ) ); + + $instance->setParameters( array( + 'page' => 'Main page|Some other page|Help:Main page|Main page' + ) ); + + $this->assertTrue( $instance->rebuild() ); + + $this->assertEquals( 3, $instance->getRebuildCount() ); + } + + /** + * @see Store::refreshData + */ + public function refreshDataOnMockCallback( &$index, $count, $namespaces, $usejobs ) { + $index++; + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/Store/Maintenance/SimplePropertyStatisticsRebuilderTest.php b/SemanticMediaWiki/tests/phpunit/includes/Store/Maintenance/SimplePropertyStatisticsRebuilderTest.php new file mode 100644 index 00000000..e993bd03 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/Store/Maintenance/SimplePropertyStatisticsRebuilderTest.php @@ -0,0 +1,117 @@ +<?php + +namespace SMW\Tests\Store\Maintenance; + +use SMW\SQLStore\SimplePropertyStatisticsRebuilder; + +use FakeResultWrapper; + +/** + * @uses \SMW\SQLStore\SimplePropertyStatisticsRebuilder + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group semantic-mediawiki-unit + * @group mediawiki-databaseless + * + * @license GNU GPL v2+ + * @since 1.9.2 + * + * @author mwjames + */ +class SimplePropertyStatisticsRebuilderTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $store = $this->getMockForAbstractClass( '\SMW\Store' ); + + $this->assertInstanceOf( + '\SMW\SQLStore\SimplePropertyStatisticsRebuilder', + new SimplePropertyStatisticsRebuilder( $store, null ) + ); + } + + public function testRebuildWithValidPropertyStatisticsStoreInsertUsageCount() { + + $arbitraryPropertyTableName = 'allornothing'; + + $propertySelectRow = new \stdClass; + $propertySelectRow->count = 1111; + + $selectResult = array( + 'smw_title' => 'Foo', + 'smw_id' => 9999 + ); + + $selectResultWrapper = new FakeResultWrapper( array( (object)$selectResult ) ); + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->atLeastOnce() ) + ->method( 'select' ) + ->will( $this->returnValue( $selectResultWrapper ) ); + + $database->expects( $this->once() ) + ->method( 'selectRow' ) + ->with( $this->stringContains( $arbitraryPropertyTableName ), + $this->anything(), + $this->equalTo( array( 'p_id' => 9999 ) ), + $this->anything() ) + ->will( $this->returnValue( $propertySelectRow ) ); + + $store = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->setMethods( array( + 'getDatabase', + 'getPropertyTables' ) ) + ->getMock(); + + $store->expects( $this->atLeastOnce() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $store->expects( $this->atLeastOnce() ) + ->method( 'getPropertyTables' ) + ->will( $this->returnValue( array( + $this->getNonFixedPropertyTable( $arbitraryPropertyTableName ) ) + ) ); + + $instance = new SimplePropertyStatisticsRebuilder( + $store, + null + ); + + $propertyStatisticsStore = $this->getMockBuilder( '\SMW\Store\PropertyStatisticsStore' ) + ->disableOriginalConstructor() + ->getMock(); + + $propertyStatisticsStore->expects( $this->atLeastOnce() ) + ->method( 'insertUsageCount' ); + + $instance->rebuild( $propertyStatisticsStore ); + } + + protected function getNonFixedPropertyTable( $propertyTableName ) { + + $propertyTable = $this->getMockBuilder( '\stdClass' ) + ->setMethods( array( + 'isFixedPropertyTable', + 'getName' ) ) + ->getMock(); + + $propertyTable->expects( $this->atLeastOnce() ) + ->method( 'isFixedPropertyTable' ) + ->will( $this->returnValue( false ) ); + + $propertyTable->expects( $this->atLeastOnce() ) + ->method( 'getName' ) + ->will( $this->returnValue( $propertyTableName ) ); + + return $propertyTable; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/StoreUpdaterTest.php b/SemanticMediaWiki/tests/phpunit/includes/StoreUpdaterTest.php new file mode 100644 index 00000000..14253d76 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/StoreUpdaterTest.php @@ -0,0 +1,202 @@ +<?php + +namespace SMW\Tests; + +use SMW\Tests\Util\SemanticDataFactory; + +use SMW\StoreUpdater; +use SMW\Application; +use SMw\Settings; +use SMW\DIWikiPage; + +/** + * @covers \SMW\StoreUpdater + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class StoreUpdaterTest extends \PHPUnit_Framework_TestCase { + + private $application; + private $semanticDataFactory; + + protected function setUp() { + parent::setUp(); + + $this->application = Application::getInstance(); + $this->semanticDataFactory = new SemanticDataFactory(); + + $settings = Settings::newFromArray( array( + 'smwgPageSpecialProperties' => array(), + 'smwgEnableUpdateJobs' => false, + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ) + ) ); + + $this->application->registerObject( 'Settings', $settings ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->application->registerObject( 'Store', $store ); + } + + protected function tearDown() { + $this->application->clear(); + + parent::tearDown(); + } + + public function testCanConstruct() { + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\StoreUpdater', + new StoreUpdater( $semanticData ) + ); + } + + public function testDoUpdateForDefaultSettings() { + + $semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->application->registerObject( 'Store', $store ); + + $instance = new StoreUpdater( $semanticData ); + $this->assertTrue( $instance->doUpdate() ); + } + + /** + * @dataProvider updateJobStatusProvider + */ + public function testDoUpdateForValidRevision( $updateJobStatus ) { + + $semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( 'updateData' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->once() ) + ->method( 'updateData' ); + + $this->application->registerObject( 'Store', $store ); + + $revision = $this->getMockBuilder( '\Revision' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $wikiPage->expects( $this->atLeastOnce() ) + ->method( 'getRevision' ) + ->will( $this->returnValue( $revision ) ); + + $pageCreator = $this->getMockBuilder( '\SMW\MediaWiki\PageCreator' ) + ->disableOriginalConstructor() + ->getMock(); + + $pageCreator->expects( $this->atLeastOnce() ) + ->method( 'createPage' ) + ->will( $this->returnValue( $wikiPage ) ); + + $this->application->registerObject( 'PageCreator', $pageCreator ); + + $instance = new StoreUpdater( $semanticData ); + $instance->setUpdateJobsEnabledState( $updateJobStatus ); + + $this->assertTrue( $instance->doUpdate() ); + } + + /** + * @dataProvider updateJobStatusProvider + */ + public function testDoUpdateForNullRevision( $updateJobStatus ) { + + $semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ ); + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->setMethods( array( 'clearData' ) ) + ->getMockForAbstractClass(); + + $store->expects( $this->once() ) + ->method( 'clearData' ) + ->with( $this->equalTo( $semanticData->getSubject() ) ); + + $this->application->registerObject( 'Store', $store ); + + $wikiPage = $this->getMockBuilder( '\WikiPage' ) + ->disableOriginalConstructor() + ->getMock(); + + $pageCreator = $this->getMockBuilder( '\SMW\MediaWiki\PageCreator' ) + ->disableOriginalConstructor() + ->getMock(); + + $pageCreator->expects( $this->atLeastOnce() ) + ->method( 'createPage' ) + ->will( $this->returnValue( $wikiPage ) ); + + $this->application->registerObject( 'PageCreator', $pageCreator ); + + $instance = new StoreUpdater( $semanticData ); + $instance->setUpdateJobsEnabledState( $updateJobStatus ); + + $this->assertTrue( $instance->doUpdate() ); + } + + public function testDoUpdateForTitleInUnknownNs() { + + $wikiPage = new DIWikiPage( + 'Foo', + -32768, // This namespace does not exist + '' + ); + + $semanticData = $this->semanticDataFactory->setSubject( $wikiPage )->newEmptySemanticData(); + $instance = new StoreUpdater( $semanticData ); + + $this->assertInternalType( 'boolean', $instance->doUpdate() ); + } + + public function testDoUpdateForSpecialPage() { + + $wikiPage = new DIWikiPage( + 'Foo', + NS_SPECIAL, + '' + ); + + $semanticData = $this->semanticDataFactory->setSubject( $wikiPage )->newEmptySemanticData(); + $instance = new StoreUpdater( $semanticData ); + + $this->assertFalse( $instance->doUpdate() ); + } + + public function updateJobStatusProvider() { + + $provider = array( + array( true ), + array( false ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/SubobjectTest.php b/SemanticMediaWiki/tests/phpunit/includes/SubobjectTest.php new file mode 100644 index 00000000..bf75fa71 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/SubobjectTest.php @@ -0,0 +1,395 @@ +<?php + +namespace SMW\Tests; + +use SMW\Tests\Util\SemanticDataValidator; + +use SMW\DataValueFactory; +use SMW\HashIdGenerator; +use SMW\DIProperty; +use SMW\DIWikiPage; +use SMW\Subobject; + +use SMWDIBlob; +use Title; + +/** + * @covers \SMW\Subobject + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SubobjectTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $title = $this->getMockBuilder( 'Title' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\Subobject', + new Subobject( $title ) + ); + } + + public function testSetSemanticWithInvalidIdThrowsException() { + + $instance = new Subobject( Title::newFromText( __METHOD__ ) ); + + $this->setExpectedException( 'InvalidArgumentException' ); + $instance->setSemanticData( '' ); + } + + public function testSetEmptySemanticData() { + + $instance = new Subobject( Title::newFromText( __METHOD__ ) ); + $instance->setEmptySemanticDataForId( 'Foo' ); + + $this->assertInstanceOf( + '\Title', + $instance->getTitle() + ); + + $this->assertInstanceOf( + '\SMWContainerSemanticData', + $instance->getSemanticData() + ); + + $this->assertEquals( + $instance->getId(), + $instance->getSemanticData()->getSubject()->getSubobjectname() + ); + } + + /** + * @dataProvider getDataProvider + */ + public function testGetId( array $parameters, array $expected ) { + + $instance = $this->acquireInstanceForId( + Title::newFromText( __METHOD__ ), + $parameters['identifier'] + ); + + if ( $expected['identifier'] !== '_' ) { + return $this->assertEquals( $expected['identifier'], $instance->getId() ); + } + + $this->assertEquals( + $expected['identifier'], + substr( $instance->getId(), 0, 1 ) + ); + } + + /** + * @dataProvider getDataProvider + */ + public function testGetProperty( array $parameters ) { + + $instance = $this->acquireInstanceForId( + Title::newFromText( __METHOD__ ), + $parameters['identifier'] + ); + + $this->assertInstanceOf( + '\SMW\DIProperty', + $instance->getProperty() + ); + } + + /** + * @dataProvider getDataProvider + */ + public function testAddDataValue( array $parameters, array $expected ) { + + $instance = $this->acquireInstanceForId( + Title::newFromText( __METHOD__ ), + $parameters['identifier'] + ); + + foreach ( $parameters['properties'] as $property => $value ){ + + $dataValue = DataValueFactory::getInstance()->newPropertyValue( + $property, + $value + ); + + $instance->addDataValue( $dataValue ); + } + + $this->assertCount( + $expected['errors'], + $instance->getErrors() + ); + + $semanticDataValidator = new SemanticDataValidator(); + + $semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance->getSemanticData() + ); + } + + /** + * @dataProvider newDataValueProvider + */ + public function testDataValueExaminer( array $parameters, array $expected ) { + + $property = $this->getMockBuilder( '\SMW\DIProperty' ) + ->disableOriginalConstructor() + ->getMock(); + + $property->expects( $this->atLeastOnce() ) + ->method( 'findPropertyTypeID' ) + ->will( $this->returnValue( $parameters['property']['typeId'] ) ); + + $property->expects( $this->atLeastOnce() ) + ->method( 'getKey' ) + ->will( $this->returnValue( $parameters['property']['key'] ) ); + + $property->expects( $this->atLeastOnce() ) + ->method( 'getLabel' ) + ->will( $this->returnValue( $parameters['property']['label'] ) ); + + $dataValue = DataValueFactory::getInstance()->newDataItemValue( + $parameters['dataItem'], + $property + ); + + $instance = $this->acquireInstanceForId( + Title::newFromText( __METHOD__ ), + 'Foo' + ); + + $instance->addDataValue( $dataValue ); + + $this->assertCount( $expected['errors'], $instance->getErrors() ); + + $semanticDataValidator = new SemanticDataValidator(); + + $semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance->getSemanticData() + ); + } + + public function testAddDataValueWithInvalidSemanticDataThrowsException() { + + $instance = new Subobject( Title::newFromText( __METHOD__ ) ); + + $this->setExpectedException( '\SMW\InvalidSemanticDataException' ); + + $instance->addDataValue( + DataValueFactory::getInstance()->newPropertyValue( 'Foo', 'Bar' ) + ); + } + + public function testGetSemanticDataInvalidSemanticDataThrowsException() { + + $instance = new Subobject( Title::newFromText( __METHOD__ ) ); + + $this->setExpectedException( '\SMW\InvalidSemanticDataException' ); + + $instance->getSemanticData(); + } + + /** + * @dataProvider getDataProvider + */ + public function testGenerateId( array $test, array $expected ) { + + $instance = new Subobject( Title::newFromText( __METHOD__ ) ); + + $actual = substr( $instance->generateId( new HashIdGenerator( $test['identifier'], '_' ) ), 0, 1 ); + + $this->assertEquals( '_', $actual ); + } + + /** + * @dataProvider getDataProvider + */ + public function testGetContainer( array $parameters, array $expected ) { + + $instance = $this->acquireInstanceForId( + Title::newFromText( __METHOD__ ), + $parameters['identifier'] + ); + + $this->assertInstanceOf( + '\SMWDIContainer', + $instance->getContainer() + ); + } + + /** + * @return array + */ + public function getDataProvider() { + + $provider = array(); + + // #0 / asserting conditions for a named identifier + $provider[] = array( + array( + 'identifier' => 'Bar', + 'properties' => array( 'Foo' => 'bar' ) + ), + array( + 'errors' => 0, + 'identifier' => 'Bar', + 'propertyCount' => 1, + 'propertyLabels' => 'Foo', + 'propertyValues' => 'Bar', + ) + ); + + // #1 / asserting conditions for an anon identifier + $provider[] = array( + array( + 'identifier' => '', + 'properties' => array( 'FooBar' => 'bar Foo' ) + ), + array( + 'errors' => 0, + 'identifier' => '_', + 'propertyCount' => 1, + 'propertyLabels' => 'FooBar', + 'propertyValues' => 'Bar Foo', + ) + ); + + // #2 / asserting conditions + $provider[] = array( + array( + 'identifier' => 'foo', + 'properties' => array( 9001 => 1001 ) + ), + array( + 'errors' => 0, + 'identifier' => 'foo', + 'propertyCount' => 1, + 'propertyLabels' => array( 9001 ), + 'propertyValues' => array( 1001 ), + ) + ); + + // #3 + $provider[] = array( + array( + 'identifier' => 'foo bar', + 'properties' => array( 1001 => 9001, 'Foo' => 'Bar' ) + ), + array( + 'errors' => 0, + 'identifier' => 'foo bar', + 'propertyCount' => 2, + 'propertyLabels' => array( 1001, 'Foo' ), + 'propertyValues' => array( 9001, 'Bar' ), + ) + ); + + // #4 / asserting that a property with a leading underscore would produce an error + $provider[] = array( + array( + 'identifier' => 'bar', + 'properties' => array( '_FooBar' => 'bar Foo' ) + ), + array( + 'errors' => 1, + 'identifier' => 'bar', + 'propertyCount' => 0, + 'propertyLabels' => '', + 'propertyValues' => '', + ) + ); + + // #5 / asserting that an inverse property would produce an error + $provider[] = array( + array( + 'identifier' => 'bar', + 'properties' => array( '-FooBar' => 'bar Foo' ) + ), + array( + 'errors' => 1, + 'identifier' => 'bar', + 'propertyCount' => 0, + 'propertyLabels' => '', + 'propertyValues' => '', + ) + ); + + // #6 / asserting that an improper value for a _wpg property would add "Has improper value for" + $diPropertyError = new DIProperty( DIProperty::TYPE_ERROR ); + + $provider[] = array( + array( + 'identifier' => 'bar', + 'properties' => array( 'Foo' => '' ) + ), + array( + 'identifier' => 'bar', + 'errors' => 1, + 'propertyCount' => 1, + 'propertyLabels' => array( $diPropertyError->getLabel() ), + 'propertyValues' => 'Foo', + ) + ); + + return $provider; + } + + /** + * Provides sample data for various dataItem/datValues + * + * @return array + */ + public function newDataValueProvider() { + + $provider = array(); + + // #0 Bug 49530 + $provider[] = array( + array( + 'property' => array( + 'typeId' => '_txt', + 'label' => 'Blob.example', + 'key' => 'Blob.example' + ), + 'dataItem' => new SMWDIBlob( '<a href="http://username@example.org/path">Example</a>' ) + ), + array( + 'errors' => 0, + 'propertyCount' => 1, + 'propertyLabels' => 'Blob.example', + 'propertyValues' => '<a href="http://username@example.org/path">Example</a>', + ) + ); + + return $provider; + } + + /** + * @return Subobject + */ + private function acquireInstanceForId( Title $title, $id = '' ) { + + $instance = new Subobject( $title ); + + if ( $id === '' && $id !== null ) { + $id = $instance->generateId( new HashIdGenerator( rand( 10, 10000 ), '_' ) ); + } + + $instance->setEmptySemanticDataForId( $id ); + + return $instance; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/articlepages/ConceptPageTest.php b/SemanticMediaWiki/tests/phpunit/includes/articlepages/ConceptPageTest.php new file mode 100644 index 00000000..bd2104d3 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/articlepages/ConceptPageTest.php @@ -0,0 +1,55 @@ +<?php + +namespace SMW\Test; + +use SMW\ConceptPage; + +/** + * Tests for the ConceptPage class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\ConceptPage + * + * @ingroup Pages + * + * @group SMW + * @group SMWExtension + */ +class ConceptPageTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\ConceptPage'; + } + + /** + * Helper method that returns a ConceptPage object + * + * @return ConceptPage + */ + private function getInstance() { + return new ConceptPage( $this->newTitle() ); + } + + /** + * @test ConceptPage::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->getInstance() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/articlepages/PropertyPageTest.php b/SemanticMediaWiki/tests/phpunit/includes/articlepages/PropertyPageTest.php new file mode 100644 index 00000000..4c403ab2 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/articlepages/PropertyPageTest.php @@ -0,0 +1,55 @@ +<?php + +namespace SMW\Test; + +use SMWPropertyPage; + +/** + * Tests for the SMWPropertyPage class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMWPropertyPage + * + * @ingroup Pages + * + * @group SMW + * @group SMWExtension + */ +class PropertyPageTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMWPropertyPage'; + } + + /** + * Helper method that returns a SMWPropertyPage object + * + * @return SMWPropertyPage + */ + private function getInstance() { + return new SMWPropertyPage( $this->newTitle() ); + } + + /** + * @test SMWPropertyPage::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->getInstance() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/cache/CacheHandlerTest.php b/SemanticMediaWiki/tests/phpunit/includes/cache/CacheHandlerTest.php new file mode 100644 index 00000000..94bd0459 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/cache/CacheHandlerTest.php @@ -0,0 +1,178 @@ +<?php + +namespace SMW\Test; + +use SMW\CacheIdGenerator; +use SMW\CacheHandler; + +use HashBagOStuff; + +/** + * @covers \SMW\CacheHandler + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class CacheHandlerTest extends SemanticMediaWikiTestCase { + + /** + * @return string + */ + public function getClass() { + return '\SMW\CacheHandler'; + } + + /** + * @note HashBagOStuff is used as test interface because it stores + * content in an associative array (which is not going to persist) + * + * @return CacheHandler + */ + private function newInstance() { + return new CacheHandler( new HashBagOStuff ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + $this->assertInstanceOf( 'BagOStuff', $this->newInstance()->getCache() ); + } + + /** + * @since 1.9 + */ + public function testNewFromId() { + + CacheHandler::reset(); + + $instance = CacheHandler::newFromId( 'hash' ); + + $this->assertFalse( + $instance->isEnabled(), + 'Asserts that with no key and valid cacheId, the cache is disabled' + ); + + $instance->setCacheEnabled( true )->setKey( new CacheIdGenerator( 'lila' ) ); + $this->assertTrue( + $instance->isEnabled(), + 'Asserts that with an avilable key and valid cacheId, the cache is enabled' + ); + + // Static + $this->assertTrue( + $instance === CacheHandler::newFromId( 'hash' ), + 'Asserts a static instance' + ); + + $instance->reset(); + + $this->assertTrue( + $instance !== CacheHandler::newFromId( 'hash' ), + 'Asserts that the instance have been reset' + ); + + $instance = CacheHandler::newFromId( 'lula' ); + + $this->assertFalse( + $instance->isEnabled(), + 'Asserts that with no key and invalid cacheId, the cache is disabled' + ); + + $instance->setCacheEnabled( true )->setKey( new CacheIdGenerator( 'lila' ) ); + + $this->assertFalse( + $instance->isEnabled(), + 'Asserts that with an available key but invalid cacheId, the cache is disabled' + ); + + $this->assertTrue( + $instance === CacheHandler::newFromId( 'lula' ), + 'Asserts a static instance' + ); + + $instance->reset(); + + $this->assertTrue( + $instance !== CacheHandler::newFromId( 'lula' ), + 'Asserts that the instance have been reset' + ); + + } + + /** + * @dataProvider keyItemDataProvider + * + * @since 1.9 + */ + public function testEnabledCache( $key, $item ) { + + $instance = $this->newInstance(); + + // Assert key handling + $instance->setCacheEnabled( true )->setKey( new CacheIdGenerator( $key ) ); + $instanceKey = $instance->getKey(); + + // Assert storage and retrieval + $instance->set( $item ); + $this->assertEquals( $item, $instance->get() ); + + // Assert deletion + $instance->delete(); + + $this->assertEmpty( $instance->get() ); + $this->assertEquals( $instanceKey, $instance->getKey() ); + + // Set key + $instance->setCacheEnabled( true )->setKey( new CacheIdGenerator( $key, 'test-prefix' ) ); + $this->assertContains( 'test-prefix' , $instance->getKey() ); + + } + + /** + * @dataProvider keyItemDataProvider + * + * @since 1.9 + */ + public function testDisabledCache( $key, $item ) { + + $instance = $this->newInstance(); + + // Assert key handling + $instance->setCacheEnabled( false )->setKey( new CacheIdGenerator( $key ) ); + $instanceKey = $instance->getKey(); + + // Assert storage and retrieval + $instance->set( $item ); + $this->assertEmpty( $instance->get() ); + + // Assert deletion + $instance->delete(); + + $this->assertEmpty( $instance->get() ); + $this->assertEquals( $instanceKey, $instance->getKey() ); + } + + /** + * @return array + */ + public function keyItemDataProvider() { + + $key = $this->newRandomString( 10 ); + + $item = array( + $this->newRandomString( 10 ), + $this->newRandomString( 20 ) + ); + + return array( array( $key, $item ) ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/cache/CacheIdGeneratorTest.php b/SemanticMediaWiki/tests/phpunit/includes/cache/CacheIdGeneratorTest.php new file mode 100644 index 00000000..ee57d371 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/cache/CacheIdGeneratorTest.php @@ -0,0 +1,101 @@ +<?php + +namespace SMW\Test; + +use SMW\CacheIdGenerator; + +/** + * @covers \SMW\CacheIdGenerator + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class CacheIdGeneratorTest extends SemanticMediaWikiTestCase { + + /** + * Holds original values of MediaWiki configuration settings + * @var array + */ + private $mwGlobals = array(); + + /** Set-up */ + protected function setUp() { + parent::setUp(); + + $this->mwGlobals['wgCachePrefix'] = $GLOBALS['wgCachePrefix']; + $GLOBALS['wgCachePrefix'] = 'smw-test'; + } + + /** Tear down */ + protected function tearDown() { + $GLOBALS['wgCachePrefix'] = $this->mwGlobals['wgCachePrefix']; + $this->mwGlobals = array(); + + parent::tearDown(); + } + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\CacheIdGenerator'; + } + + /** + * @since 1.9 + * + * @return CacheIdGenerator + */ + private function newInstance( $hashable = null, $prefix = null ) { + return new CacheIdGenerator( $hashable, $prefix ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testGetPrefix() { + + $instance = $this->newInstance( null, null ); + $this->assertInternalType( 'string', $instance->getPrefix() ); + $this->assertContains( 'smw-test:smw', $instance->getPrefix() ); + + $prefix = $this->newRandomString(); + $instance = $this->newInstance( null, $prefix ); + + $this->assertInternalType( 'string', $instance->getPrefix() ); + $this->assertContains( 'smw-test:smw:' . $prefix, $instance->getPrefix() ); + + } + + /** + * @since 1.9 + */ + public function testGenerateId() { + + $hashable = $this->newRandomString(); + $prefix = $this->newRandomString(); + + $instance = $this->newInstance( $hashable, null ); + $this->assertInternalType( 'string', $instance->generateId() ); + + $instance = $this->newInstance( $hashable, $prefix ); + $this->assertInternalType( 'string', $instance->generateId() ); + $this->assertContains( $prefix, $instance->generateId() ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/cache/CacheableResultMapperTest.php b/SemanticMediaWiki/tests/phpunit/includes/cache/CacheableResultMapperTest.php new file mode 100644 index 00000000..50dc4e37 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/cache/CacheableResultMapperTest.php @@ -0,0 +1,81 @@ +<?php + +namespace SMW\Test; + +use SMW\CacheableResultMapper; +use SMW\SimpleDictionary; + +/** + * @covers \SMW\CacheableResultMapper + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class CacheableResultMapperTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\CacheableResultMapper'; + } + + /** + * @since 1.9 + * + * @return CacheableResultMapper + */ + private function newInstance( $cacheId = 'Foo', $cacheEnabled = true, $cacheExpiry = 10 ) { + + $setup = array( + 'id' => $cacheId, + 'prefix' => 'test', + 'type' => 'hash', + 'enabled' => $cacheEnabled, + 'expiry' => $cacheExpiry + ); + + return new CacheableResultMapper( new SimpleDictionary( $setup ) ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testRoundTrip() { + + $id = $this->newRandomString(); + $expected = array( $this->newRandomString(), $this->newRandomString() ); + $instance = $this->newInstance( $id, true, rand( 100, 200 ) ); + + // Initial fetch(without any data present) must fail + $result = $instance->fetchFromCache(); + $this->assertFalse( $result ); + $this->assertInternalType( 'null', $instance->getCacheDate() ); + + // Cache object + $instance->recache( $expected ); + + // Re-fetch data from cache + $result = $instance->fetchFromCache(); + + $this->assertInternalType( 'array', $result ); + $this->assertInternalType( 'string', $instance->getCacheDate() ); + $this->assertEquals( $expected, $result ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/context/EmptyContextTest.php b/SemanticMediaWiki/tests/phpunit/includes/context/EmptyContextTest.php new file mode 100644 index 00000000..e57a2b51 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/context/EmptyContextTest.php @@ -0,0 +1,59 @@ +<?php + +namespace SMW\Test; + +use SMW\EmptyContext; + +/** + * @covers \SMW\EmptyContext + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class EmptyContextTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\EmptyContext'; + } + + /** + * @since 1.9 + * + * @return EmptyContext + */ + private function newInstance() { + return new EmptyContext(); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testGetStore() { + $this->assertNull( $this->newInstance()->getStore() ); + } + + /** + * @since 1.9 + */ + public function testGetSettings() { + $this->assertNull( $this->newInstance()->getSettings() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/context/ExtensionContextTest.php b/SemanticMediaWiki/tests/phpunit/includes/context/ExtensionContextTest.php new file mode 100644 index 00000000..1a31bbf7 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/context/ExtensionContextTest.php @@ -0,0 +1,124 @@ +<?php + +namespace SMW\Test; + +use SMW\ExtensionContext; + +/** + * @covers \SMW\ExtensionContext + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class ExtensionContextTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\ExtensionContext'; + } + + /** + * @since 1.9 + * + * @return ExtensionContext + */ + private function newInstance( $builder = null ) { + return new ExtensionContext( $builder ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testGetSettings() { + + $settings = $this->newSettings( array( 'Foo' => 'Bar' ) ); + $instance = $this->newInstance(); + $instance->getDependencyBuilder()->getContainer()->registerObject( 'Settings', $settings ); + + $this->assertInstanceOf( + '\SMW\Settings', + $instance->getSettings(), + 'Asserts that getSettings() yields a Settings object' + ); + + $this->assertEquals( + $settings, + $instance->getSettings(), + 'Asserts that getSettings() yields an expected result' + ); + + $this->assertTrue( + $instance->getSettings() === $instance->getDependencyBuilder()->newObject( 'Settings' ), + "Asserts that getSettings() returns the same instance (syncronized object instance)" + ); + + } + + /** + * @since 1.9 + */ + public function testGetStore() { + + $store = $this->newMockBuilder()->newObject( 'Store' ); + $instance = $this->newInstance(); + $instance->getDependencyBuilder()->getContainer()->registerObject( 'Store', $store ); + + $this->assertInstanceOf( + '\SMW\Store', + $instance->getStore(), + 'Asserts that getStore() yields a Store object' + ); + + $this->assertEquals( + $store, + $instance->getStore(), + 'Asserts that getSettings() yields an expected result' + ); + + $this->assertTrue( + $instance->getStore() === $instance->getDependencyBuilder()->newObject( 'Store' ), + "Asserts that getStore() returns the same instance (syncronized object instance)" + ); + + } + + /** + * @since 1.9 + */ + public function testSetGetDependencyBuilder() { + + $builder = $this->newDependencyBuilder(); + $instance = $this->newInstance(); + + $this->assertInstanceOf( + '\SMW\DependencyBuilder', + $instance->getDependencyBuilder(), + 'Asserts that getDependencyBuilder() yields a default DependencyBuilder object' + ); + + $instance = $this->newInstance( $builder ); + + $this->assertTrue( + $builder === $instance->getDependencyBuilder(), + 'Asserts that getDependencyBuilder() yields the same instance used for constructor injection' + ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/dataitems/DIConceptTest.php b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DIConceptTest.php new file mode 100644 index 00000000..4630df87 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DIConceptTest.php @@ -0,0 +1,95 @@ +<?php + +namespace SMW\Tests; + +/** + * @covers \SMW\DIConcept + * + * @group SMW + * @group SMWExtension + * @group SMWDataItems + * + * @license GNU GPL v2+ + * @author mwjames + */ +class DIConceptTest extends DataItemTest { + + /** + * Returns the name of the class to be tested + * + * @since 1.8 + * + * @return string + */ + public function getClass() { + return 'SMW\DIConcept'; + } + + /** + * @see DataItemTest::constructorProvider + * + * @since 1.8 + * + * @return array + */ + public function constructorProvider() { + return array( + array( 'Foo', '', '', '', '' ), + ); + } + + /** + * @see DataItemTest::invalidConstructorArgsProvider + * + * @since 1.9 + * + * @return array + */ + public function invalidConstructorArgsProvider() { + return array( + array( 'Bar' ), + ); + } + + /** + * @test DIConcept::setCacheStatus + * @test DIConcept::setCacheDate + * @test DIConcept::setCacheCount + * @dataProvider conceptCacheDataProvider + * + * @since 1.9 + * + * @param $status + * @param $date + * @param $count + */ + public function testConceptCacheSetterGetter( $status, $date, $count ) { + + $reflector = new \ReflectionClass( $this->getClass() ); + $instance = $reflector->newInstanceArgs( array ( 'Foo', '', '', '', '' ) ); + + $instance->setCacheStatus( $status ); + $instance->setCacheDate( $date ) ; + $instance->setCacheCount( $count ); + + $this->assertEquals( $status, $instance->getCacheStatus() ); + $this->assertEquals( $date, $instance->getCacheDate() ); + $this->assertEquals( $count, $instance->getCacheCount() ); + + } + + /** + * Data provider for testing concept cache setter/getter + * + * @since 1.9 + * + * @return array + */ + public function conceptCacheDataProvider() { + return array( + array( 'empty', '', '' ), + array( 'full', '1358515326', '1000' ), + ); + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/dataitems/DIPropertyTest.php b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DIPropertyTest.php new file mode 100644 index 00000000..51200bf8 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DIPropertyTest.php @@ -0,0 +1,92 @@ +<?php + +namespace SMW\Tests; + +use SMW\DIProperty; + +/** + * @covers \SMW\DIProperty + * @covers SMWDataItem + * + * @group SMW + * @group SMWExtension + * @group SMWDataItems + * + * @author Nischay Nahata + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class DIPropertyTest extends DataItemTest { + + /** + * @see DataItemTest::getClass + * + * @since 1.8 + * + * @return string + */ + public function getClass() { + return '\SMWDIProperty'; + } + + /** + * @see DataItemTest::constructorProvider + * + * @since 1.8 + * + * @return array + */ + public function constructorProvider() { + return array( + array( 0 ), + array( 243.35353 ), + array( 'ohi there' ), + ); + } + + /** + * @see DataItemTest::invalidConstructorArgsProvider + * + * @since 1.9 + * + * @return array + */ + public function invalidConstructorArgsProvider() { + return array( + array( true ), + array( array() ), + ); + } + + public function testSetPropertyTypeIdOnUserDefinedProperty() { + + $property = new DIProperty( 'SomeBlobProperty' ); + $property->setPropertyTypeId( '_txt' ); + + $this->assertEquals( '_txt', $property->findPropertyTypeID() ); + } + + public function testSetPropertyTypeIdOnPredefinedProperty() { + + $property = new DIProperty( '_MDAT' ); + $property->setPropertyTypeId( '_dat' ); + + $this->assertEquals( '_dat', $property->findPropertyTypeID() ); + } + + public function testSetUnknownPropertyTypeIdThrowsException() { + + $property = new DIProperty( 'SomeUnknownTypeIdProperty' ); + + $this->setExpectedException( 'RuntimeException' ); + $property->setPropertyTypeId( '_unknownTypeId' ); + } + + public function testSetPropertyTypeIdOnPredefinedPropertyThrowsException() { + + $property = new DIProperty( '_MDAT' ); + + $this->setExpectedException( 'InvalidArgumentException' ); + $property->setPropertyTypeId( '_txt' ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/dataitems/DIWikiPageTest.php b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DIWikiPageTest.php new file mode 100644 index 00000000..88eedaab --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DIWikiPageTest.php @@ -0,0 +1,53 @@ +<?php + +namespace SMW\Tests; + +use SMW\DIWikiPage; + +/** + * @covers \SMW\DIWikiPage + * @covers SMWDataItem + * + * @group SMW + * @group SMWExtension + * @group SMWDataItems + * + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class DIWikiPageTest extends DataItemTest { + + /** + * @see DataItemTest::getClass + * + * @since 1.9 + * + * @return string + */ + public function getClass() { + return 'SMW\DIWikiPage'; + } + + /** + * @see DataItemTest::constructorProvider + * + * @since 1.9 + * + * @return array + */ + public function constructorProvider() { + return array( + array( 'Foo', NS_MAIN, '' ), + array( 'Foo_Bar', NS_MAIN, '' ), + array( 'Foo_Bar_Baz', NS_MAIN, '', 'spam' ), + ); + } + + /** + * @dataProvider instanceProvider + */ + public function testGetTitleAndNewFromTitleRoundrtip( DIWikiPage $di ) { + $newDi = DIWikiPage::newFromTitle( $di->getTitle() ); + $this->assertTrue( $newDi->equals( $di ) ); + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_BlobTest.php b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_BlobTest.php new file mode 100644 index 00000000..628c13b0 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_BlobTest.php @@ -0,0 +1,49 @@ +<?php + +namespace SMW\Tests; + +/** + * @covers SMWDIBlob + * @covers SMWDataItem + * + * @file + * @since 1.8 + * + * @ingroup SMW + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group SMWDataItems + * + * @author Nischay Nahata + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class DIBlobTest extends DataItemTest { + + /** + * @see DataItemTest::getClass + * + * @since 1.8 + * + * @return string + */ + public function getClass() { + return '\SMWDIBlob'; + } + + /** + * @see DataItemTest::constructorProvider + * + * @since 1.8 + * + * @return array + */ + public function constructorProvider() { + return array( + array( 'I love Semantic MediaWiki' ), + array( 'It is open source' ), + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_BoolTest.php b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_BoolTest.php new file mode 100644 index 00000000..6d5d5262 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_BoolTest.php @@ -0,0 +1,64 @@ +<?php + +namespace SMW\Tests; + +/** + * @covers SMWDIBoolean + * @covers SMWDataItem + * + * @file + * @since 1.8 + * + * @ingroup SMW + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group SMWDataItems + * + * @author Nischay Nahata + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class SMWDIBooleanTest extends DataItemTest { + + /** + * @see DataItemTest::getClass + * + * @since 1.8 + * + * @return string + */ + public function getClass() { + return '\SMWDIBoolean'; + } + + /** + * @see DataItemTest::constructorProvider + * + * @since 1.8 + * + * @return array + */ + public function constructorProvider() { + return array( + array( false ), + array( true ), + ); + } + + /** + * @see DataItemTest::invalidConstructorArgsProvider + * + * @since 1.9 + * + * @return array + */ + public function invalidConstructorArgsProvider() { + return array( + array( 42 ), + array( array() ), + array( 'abc' ), + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_GeoCoordTest.php b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_GeoCoordTest.php new file mode 100644 index 00000000..c6d2a420 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_GeoCoordTest.php @@ -0,0 +1,49 @@ +<?php + +namespace SMW\Tests; + +/** + * @covers SMWDIGeoCoord + * @covers SMWDataItem + * + * @file + * @since 1.8 + * + * @ingroup SMW + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group SMWDataItems + * + * @author Nischay Nahata + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class SMWDIGeoCoordTest extends DataItemTest { + + /** + * @see DataItemTest::getClass + * + * @since 1.8 + * + * @return string + */ + public function getClass() { + return '\SMWDIGeoCoord'; + } + + /** + * @see DataItemTest::constructorProvider + * + * @since 1.8 + * + * @return array + */ + public function constructorProvider() { + return array( + array( array( 'lat' => 83.34, 'lon' => 38.44, 'alt' => 54 ) ), + array( array( 'lat' => 42.43, 'lon' => 33.32 ) ), + ); + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_NumberTest.php b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_NumberTest.php new file mode 100644 index 00000000..8e13c3c1 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_NumberTest.php @@ -0,0 +1,65 @@ +<?php + +namespace SMW\Tests; + +/** + * @covers SMWDINumber + * @covers SMWDataItem + * + * @file + * @since 1.8 + * + * @ingroup SMW + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group SMWDataItems + * @group SMWDINumberTest + * + * @author Nischay Nahata + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class SMWDINumberTest extends DataItemTest { + + /** + * @see DataItemTest::getClass + * + * @since 1.8 + * + * @return string + */ + public function getClass() { + return '\SMWDINumber'; + } + + /** + * @see DataItemTest::constructorProvider + * + * @since 1.8 + * + * @return array + */ + public function constructorProvider() { + return array( + array( 0 ), + array( 243.35353 ), + ); + } + + /** + * @see DataItemTest::invalidConstructorArgsProvider + * + * @since 1.9 + * + * @return array + */ + public function invalidConstructorArgsProvider() { + return array( + array( true ), + array( array() ), + array( 'abc' ), + ); + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/dataitems/DataItemTest.php b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DataItemTest.php new file mode 100644 index 00000000..fee76cec --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/dataitems/DataItemTest.php @@ -0,0 +1,144 @@ +<?php + +namespace SMW\Tests; + +use SMW\Tests\MwDBaseUnitTestCase; + +use SMWDataItem; + +/** + * Base class for SMW\DataItem tests. + * + * @file + * @since 1.8 + * + * @ingroup SMW + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group SMWDataItems + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +abstract class DataItemTest extends MwDBaseUnitTestCase { + + /** + * Returns the name of the \SMW\DataItem deriving class this test tests. + * + * @since 1.8 + * + * @return string + */ + public abstract function getClass(); + + /** + * @since 1.8 + * + * @return array + */ + public abstract function constructorProvider(); + + /** + * @since 1.9 + * + * @return array + */ + public function invalidConstructorArgsProvider() { + return array(); + } + + public function testConstructWithInvalidArgsThrowsException() { + $this->assertTrue( true ); + + foreach ( $this->invalidConstructorArgsProvider() as $argList ) { + $this->assertConstructWithInvalidArgsThrowsException( $argList ); + } + } + + protected function assertConstructWithInvalidArgsThrowsException( array $argList ) { + $this->setExpectedException( 'Exception' ); + + call_user_func_array( + array( $this, 'newInstance' ), + $argList + ); + } + + /** + * Creates and returns a new instance of the data item. + * + * @since 1.8 + * + * @return SMWDataItem + */ + public function newInstance() { + $reflector = new \ReflectionClass( $this->getClass() ); + $args = func_get_args(); + $instance = $reflector->newInstanceArgs( $args ); + return $instance; + } + + /** + * @since 1.8 + * + * @return array + */ + public function instanceProvider() { + $phpFails = array( $this, 'newInstance' ); + + return array_map( + function( array $args ) use ( $phpFails ) { + return array( call_user_func_array( $phpFails, $args ) ); + }, + $this->constructorProvider() + ); + } + + /** + * @dataProvider constructorProvider + * + * @since 1.8 + */ + public function testConstructor() { + $dataItem = call_user_func_array( + array( $this, 'newInstance' ), + func_get_args() + ); + + $this->assertInstanceOf( '\SMWDataItem', $dataItem ); + $this->assertInstanceOf( $this->getClass(), $dataItem ); + } + + /** + * @dataProvider instanceProvider + * + * @since 1.8 + * + * @param \SMWDataItem $dataItem + */ + public function testSerialization( \SMWDataItem $dataItem ) { + $class = $this->getClass(); + + $this->assertEquals( + $dataItem, + $class::doUnserialize( $dataItem->getSerialization() ) + ); + } + + /** + * @dataProvider instanceProvider + */ + public function testInstanceEqualsItself( SMWDataItem $di ) { + $this->assertTrue( $di->equals( $di ) ); + } + + /** + * @dataProvider instanceProvider + */ + public function testInstanceDoesNotEqualNyanData( SMWDataItem $di ) { + $this->assertFalse( $di->equals( new \SMWDIBlob( '~=[,,_,,]:3' ) ) ); + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/dic/DependencyInjectorTest.php b/SemanticMediaWiki/tests/phpunit/includes/dic/DependencyInjectorTest.php new file mode 100644 index 00000000..2e914010 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/dic/DependencyInjectorTest.php @@ -0,0 +1,73 @@ +<?php + +namespace SMW\Test; + +use SMW\DependencyInjector; + +/** + * @covers \SMW\DependencyInjector + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class DependencyInjectorTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\DependencyInjector'; + } + + /** + * @since 1.9 + * + * @return DependencyBuilder + */ + private function newMockDependencyBuilder() { + + $builder = $this->getMockBuilder( '\SMW\DependencyBuilder' ) + ->disableOriginalConstructor() + ->setMethods( array( 'newObject', 'getContainer', 'getArgument', 'hasArgument', 'addArgument', 'setScope' ) ) + ->getMock(); + + return $builder; + } + + /** + * @since 1.9 + * + * @return DependencyInjector + */ + private function newInstance() { + return $this->getMockForAbstractClass( $this->getClass() ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testSetGet() { + + $instance = $this->newInstance(); + $builder = $this->newMockDependencyBuilder(); + + $instance->setDependencyBuilder( $builder ); + $this->assertEquals( $builder, $instance->getDependencyBuilder() ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/dic/NullDependencyContainerTest.php b/SemanticMediaWiki/tests/phpunit/includes/dic/NullDependencyContainerTest.php new file mode 100644 index 00000000..5020b53a --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/dic/NullDependencyContainerTest.php @@ -0,0 +1,46 @@ +<?php + +namespace SMW\Test; + +use SMW\NullDependencyContainer; + +/** + * @covers \SMW\NullDependencyContainer + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9.0.2 + * + * @author mwjames + */ +class NullDependencyContainerTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\NullDependencyContainer'; + } + + /** + * @since 1.9.0.2 + */ + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), new NullDependencyContainer ); + } + + /** + * @since 1.9.0.2 + */ + public function testLoadAllDefinitions() { + + $instance = new NullDependencyContainer; + $this->assertEquals( null, $instance->loadAllDefinitions() ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/dic/SharedDependencyContainerTest.php b/SemanticMediaWiki/tests/phpunit/includes/dic/SharedDependencyContainerTest.php new file mode 100644 index 00000000..08f032e7 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/dic/SharedDependencyContainerTest.php @@ -0,0 +1,216 @@ +<?php + +namespace SMW\Test; + +use SMW\SharedDependencyContainer; +use SMW\SimpleDependencyBuilder; + +use SMW\DependencyBuilder; +use SMW\DependencyContainer; + +/** + * @covers \SMW\SharedDependencyContainer + * @covers \SMW\SimpleDependencyBuilder + * @covers \SMW\BaseDependencyContainer + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SharedDependencyContainerTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\SimpleDependencyBuilder'; + } + + /** + * @since 1.9 + * + * @return SimpleDependencyBuilder + */ + private function newInstance( $container = null ) { + return new SimpleDependencyBuilder( $container ); + } + + /** + * @dataProvider objectDataProvider + * + * @since 1.9 + */ + public function testObjectRegistrationAndInstanitation( $objectName, $objectDefinition ) { + + $instance = $this->newInstance( new SharedDependencyContainer() ); + + foreach ( $objectDefinition as $objectInstance => $arguments ) { + + foreach ( $arguments as $name => $object ) { + $instance->addArgument( $name, $object ); + } + + $newInstance = $instance->newObject( $objectName ); + + if ( $newInstance !== null ) { + + $this->assertInstanceOf( + $objectInstance, + $newInstance, + 'Asserts that newObject() was able to create an object instance' + ); + + } + + $this->assertTrue( true ); + } + + } + + /** + * @since 1.9 + */ + public function testObjectRegistrationCompleteness() { + + $instance = new SharedDependencyContainer(); + + foreach ( $this->objectDataProvider() as $object ) { + $registeredObjects[ $object[0] ] = array() ; + } + + foreach ( $instance->toArray() as $objectName => $objectSiganture ) { + $this->assertObjectRegistration( $objectName, $registeredObjects ); + } + + foreach ( $instance->loadAllDefinitions() as $objectName => $objectSiganture ) { + $this->assertObjectRegistration( $objectName, $registeredObjects ); + } + + $this->assertTrue( true ); + } + + /** + * Asserts whether a registered object is being tested + */ + public function assertObjectRegistration( $name, $objects ) { + if ( !array_key_exists( $name, $objects ) ) { + $this->markTestIncomplete( "This test is incomplete because of a missing {$name} assertion." ); + } + } + + /** + * @return array + */ + public function objectDataProvider() { + + $provider = array(); + + $provider[] = array( 'Settings', array( '\SMW\Settings' => array() ) ); + $provider[] = array( 'Store', array( '\SMW\Store' => array() ) ); + $provider[] = array( 'CacheHandler', array( '\SMW\CacheHandler' => array() ) ); + $provider[] = array( 'ExtensionContext', array( '\SMW\ContextResource' => array() ) ); + $provider[] = array( 'NamespaceExaminer', array( '\SMW\NamespaceExaminer' => array() ) ); + + $provider[] = array( 'RequestContext', array( '\IContextSource' => array() ) ); + $provider[] = array( 'TitleCreator', array( '\SMW\Mediawiki\TitleCreator' => array() ) ); + $provider[] = array( 'PageCreator', array( '\SMW\Mediawiki\PageCreator' => array() ) ); + $provider[] = array( 'JobFactory', array( '\SMW\Mediawiki\Jobs\JobFactory' => array() ) ); + + $provider[] = array( 'RequestContext', array( '\IContextSource' => array( + 'Title' => $this->newMockBuilder()->newObject( 'Title' ), + 'Language' => $this->newMockBuilder()->newObject( 'Language' ) + ) + ) + ); + + $provider[] = array( 'WikiPage', array( '\WikiPage' => array( + 'Title' => $this->newMockBuilder()->newObject( 'Title' ) + ) + ) + ); + + $provider[] = array( 'ContentParser', array( '\SMW\ContentParser' => array( + 'Title' => $this->newMockBuilder()->newObject( 'Title' ) + ) + ) + ); + + $provider[] = array( 'NullPropertyAnnotator', array( '\SMW\PropertyAnnotator' => array( + 'SemanticData' => $this->newMockBuilder()->newObject( 'SemanticData' ) + ) + ) + ); + + $provider[] = array( 'CommonPropertyAnnotator', array( '\SMW\PropertyAnnotator' => array( + 'SemanticData' => $this->newMockBuilder()->newObject( 'SemanticData' ), + 'DefaultSort' => 'Foo', + 'CategoryLinks' => array( 'Bar' ) + ) + ) + ); + + $provider[] = array( 'PredefinedPropertyAnnotator', array( '\SMW\PropertyAnnotator' => array( + 'SemanticData' => $this->newMockBuilder()->newObject( 'SemanticData' ), + 'WikiPage' => $this->newMockBuilder()->newObject( 'WikiPage' ), + 'Revision' => $this->newMockBuilder()->newObject( 'Revision' ), + 'User' => $this->newMockBuilder()->newObject( 'User' ), + ) + ) + ); + + $provider[] = array( 'ParserData', array( '\SMW\ParserData' => array( + 'Title' => $this->newMockBuilder()->newObject( 'Title' ), + 'ParserOutput' => $this->newMockBuilder()->newObject( 'ParserOutput' ) + ) + ) + ); + + $provider[] = array( 'QueryProfiler', array( '\SMW\Query\Profiler\ProfileAnnotator' => array( + 'QueryDescription' => $this->newMockBuilder()->newObject( 'QueryDescription' ), + 'QueryParameters' => array( 'Foo' ), + 'QueryFormat' => 'Foo', + 'QueryDuration' => 0, + 'Title' => $this->newMockBuilder()->newObject( 'Title' ), + ) + ) + ); + + $provider[] = array( 'MessageFormatter', array( '\SMW\MessageFormatter' => array( + 'Language' => $this->newMockBuilder()->newObject( 'Language' ) + ) + ) + ); + + $parser = $this->newMockBuilder()->newObject( 'Parser', array( + 'getTitle' => $this->newMockBuilder()->newObject( 'Title' ), + 'getOutput' => $this->newMockBuilder()->newObject( 'ParserOutput' ), + 'getTargetLanguage' => $this->newMockBuilder()->newObject( 'Language' ) + ) ); + + $provider[] = array( 'AskParserFunction', array( '\SMW\AskParserFunction' => array( + 'Parser' => $parser + ) + ) + ); + + $provider[] = array( 'ShowParserFunction', array( '\SMW\ShowParserFunction' => array( + 'Parser' => $parser + ) + ) + ); + + $provider[] = array( 'SubobjectParserFunction', array( '\SMW\SubobjectParserFunction' => array( + 'Parser' => $parser + ) + ) + ); + + return $provider; + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php b/SemanticMediaWiki/tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php new file mode 100644 index 00000000..a1c5d1f6 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php @@ -0,0 +1,873 @@ +<?php + +namespace SMW\Test; + +use SMW\NullDependencyContainer; +use SMW\SimpleDependencyBuilder; +use SMW\DependencyBuilder; +use SMW\DependencyObject; + +use Title; + +/** + * @covers \SMW\SimpleDependencyBuilder + * @covers \SMW\BaseDependencyContainer + * @covers \SMW\DependencyInjector + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SimpleDependencyBuilderTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\SimpleDependencyBuilder'; + } + + /** + * @since 1.9 + * + * @param $data + */ + protected function getScopeDefinition( $scope ) { + $reflector = $this->newReflector( '\SMW\DependencyObject' ); + return $reflector->getConstant( $scope ); + } + + /** + * @since 1.9 + * + * @return SimpleDependencyBuilder + */ + private function newInstance( $dependencyContainer = null ) { + return new SimpleDependencyBuilder( $dependencyContainer ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testRegisterContainer() { + + $instance = $this->newInstance(); + + $container = $this->newMockBuilder()->newObject( 'FakeDependencyContainer', array( + 'toArray' => array( 'Test' => array( '123', 0 ) ) + ) ); + + // Register container + $instance->registerContainer( $container ); + + $this->assertEquals( + '123', + $instance->newObject( 'Test' ), + 'asserts object creation' + ); + + $container = $this->newMockBuilder()->newObject( 'FakeDependencyContainer', array( + 'toArray' => array( 'Test2' => array( 9001, 1 ) ) + ) ); + + // Register additional container and asserts that both objects are available + $instance->registerContainer( $container ); + + $this->assertEquals( + '123', + $instance->newObject( 'Test' ), + 'asserts object creation after container merge' + ); + + $this->assertEquals( + 9001, + $instance->newObject( 'Test2' ), + 'asserts object creation after container merge' + ); + + } + + /** + * Register another container containing the same identifier but + * with a different definition + * + * @since 1.9 + */ + public function testRegisterContainerWithSameIdentifier() { + + $instance = $this->newInstance(); + + $container = $this->newMockBuilder()->newObject( 'FakeDependencyContainer', array( + 'toArray' => array( 'Test' => array( 9001, 1 ) ) + ) ); + + $instance->registerContainer( $container ); + + $this->assertEquals( + 9001, + $instance->newObject( 'Test' ), + 'Asserts object creation after container merge' + ); + + $container = $this->newMockBuilder()->newObject( 'FakeDependencyContainer', array( + 'toArray' => array( 'Test' => array( 1009, 0 ) ) + ) ); + + $instance->registerContainer( $container ); + + $this->assertEquals( + 9001, + $instance->newObject( 'Test' ), + 'Asserts object definition has not been overridden' + ); + + } + + /** + * @since 1.9 + */ + public function testRegisterObject() { + + $instance = $this->newInstance(); + + $instance->getContainer()->registerObject( 'Test', new \stdClass ); + + $this->assertInstanceOf( + '\stdClass', + $instance->newObject( 'Test' ), + 'asserts registration of an object' + ); + + } + + /** + * @since 1.9 + */ + public function testRegisterObjectUsingMagicMethodEagerLoading() { + + $instance = $this->newInstance(); + $container = new NullDependencyContainer(); + + // Eager loading + $container->someFunnyTitle = $this->newTitle(); + + // Register container + $instance->registerContainer( $container ); + + $this->assertInstanceOf( + 'Title', + $instance->someFunnyTitle(), 'asserts invoked instance' + ); + + } + + /** + * @since 1.9 + */ + public function testRegisterObjectUsingMagicMethodLazyLoading() { + + $instance = $this->newInstance(); + $container = new NullDependencyContainer(); + + $container->someFunnyTitle = $this->newTitle(); + $container->FakeWikiPage = function ( DependencyBuilder $builder ) { + return FakeWikiPage::newFromTitle( $builder->getArgument( 'Title' ) ); + }; + + // Register container + $instance->registerContainer( $container ); + + // Adds necessary argument object needed for the FakeWikiPage build process + $instance->addArgument( 'Title', $instance->someFunnyTitle() ); + + $this->assertInstanceOf( + '\SMW\Test\FakeWikiPage', + $instance->FakeWikiPage(), + 'asserts invoked instance using __call method' + ); + + $this->assertInstanceOf( + '\SMW\Test\FakeWikiPage', + $instance->newObject( 'FakeWikiPage' ), + 'asserts invoked instance using newObject()' + ); + + $this->assertTrue( + $instance->FakeWikiPage() !== $instance->newObject( 'FakeWikiPage' ), + 'asserts that created instances are different' + ); + + } + + /** + * @since 1.9 + */ + public function testRegisterObjectUsingMagicMethodViaBuilder() { + + $instance = $this->newInstance(); + + // Clear registered container + $instance->registerContainer( new NullDependencyContainer() ); + + // Object is using an argument that where invoked using the __set method + // and is evenly accessible during the build process using newObject() + // method + $instance->getContainer()->quux = $this->newTitle(); + $instance->getContainer()->Baz = function ( DependencyBuilder $builder ) { + return FakeWikiPage::newFromTitle( $builder->newObject( 'quux' ) ); + }; + + $this->assertInstanceOf( + 'Title', + $instance->newObject( 'quux' ), + 'asserts object instance using newObject() method' + ); + + $this->assertInstanceOf( + '\SMW\Test\FakeWikiPage', + $instance->newObject( 'Baz' ), + 'asserts object instance using newObject() method' + ); + + $this->assertInstanceOf( + '\SMW\Test\FakeWikiPage', + $instance->Baz(), + 'asserts object instance using __call method' + ); + + } + + /** + * @since 1.9 + */ + public function testAddGetArguments() { + + // Add argument using a setter ("real" object) + $instance = $this->newInstance(); + $title = $this->newTitle( NS_MAIN, 'Lala' ); + + $instance->addArgument( 'Title', $title ); + $instance->getContainer()->registerObject( 'Foo', function ( DependencyBuilder $builder ) { + return FakeWikiPage::newFromTitle( $builder->getArgument( 'Title' ) ); + } ); + + $this->assertEquals( + $title, + $instance->newObject( 'Foo' )->getTitle(), + 'asserts object instance using newObject() method' + ); + + } + + /** + * @since 1.9 + */ + public function testAddGetArgumentsOnMockObject() { + + $instance = $this->newInstance(); + $mockTitle = $this->newMockBuilder()->newObject( 'Title' ); + + $instance->addArgument( 'Title', $mockTitle ); + $instance->getContainer()->registerObject( 'bar', function ( DependencyBuilder $builder ) { + return FakeWikiPage::newFromTitle( $builder->getArgument( 'Title' ) ); + } ); + + $this->assertInstanceOf( + '\SMW\Test\FakeWikiPage', + $instance->newObject( 'bar' ), + 'asserts object instance using newObject() method' + ); + + $this->assertInstanceOf( + 'Title', + $instance->newObject( 'bar' )->getTitle(), + 'asserts object instance using newObject() method' + ); + + $this->assertInstanceOf( + 'Title', + $instance->bar()->getTitle(), + 'asserts object instance using __call method' + ); + + } + + /** + * @dataProvider autoArgumentsDataProvider + * + * @since 1.9 + */ + public function testAutoArguments( $setup, $expected ) { + + $instance = $this->newInstance(); + + $instance->getContainer()->registerObject( 'Baz', function ( DependencyBuilder $builder ) { + return FakeWikiPage::newFromTitle( $builder->getArgument( 'Title' ) ); + } ); + + $this->assertEquals( + $expected, + $instance->newObject( 'Baz', $setup )->getTitle(), + 'asserts that newObject() and arguments return expected results' + ); + + $this->assertEquals( + $expected, + $instance->Baz( $setup )->getTitle(), + 'asserts that __call and arguments return expected results' + ); + + } + + /** + * @dataProvider scopeDataProvider + * + * @since 1.9 + */ + public function testCompareScope( $setup, $expected ) { + + $instance = $this->newInstance(); + $scope = $this->getScopeDefinition( $setup['scope'] ); + $title = $this->newTitle( NS_MAIN, 'Lila' ); + + // Lazy loading or deferred instantiation + $instance->getContainer()->registerObject( 'Test', function ( DependencyBuilder $builder ) { + return FakeWikiPage::newFromTitle( $builder->getArgument( 'Title' ) ); + }, $scope ); + + $newInstance = $instance->newObject( 'Test', array( $title ) ); + + $this->assertEquals( + $title, + $newInstance->getTitle(), + 'asserts object instance using newObject() constructor' + ); + + $this->assertEquals( + $expected, + $newInstance === $instance->newObject( 'Test', array( $title ) ), + 'asserts whether instances are equal to the selected scope' + ); + + // Eager loading, means that the object is created during initialization and not + // during execution which is forcing the object to be created instantly + $instance->getContainer()->registerObject( 'Title', $this->newTitle(), $scope ); + + $newInstance = $instance->newObject( 'Title' ); + + $this->assertTrue( + $newInstance === $instance->newObject( 'Title' ), + 'asserts that objects using an eager loading approach are always of prototype scope' + ); + + } + + /** + * @since 1.9 + */ + public function testResetScopeLazyLoading() { + + $instance = $this->newInstance(); + $container = $instance->getContainer(); + $title = $this->newTitle( NS_MAIN, 'Scope' ); + + $instance->getContainer()->registerObject( 'Scope', function ( DependencyBuilder $builder ) { + return FakeWikiPage::newFromTitle( $builder->getArgument( 'Title' ) ); + }, DependencyObject::SCOPE_SINGLETON ); + + $singleton = $instance->newObject( 'Scope', array( $title ) ); + $this->assertEquals( $title, $singleton->getTitle() ); + + $this->assertTrue( + $singleton === $instance->newObject( 'Scope', array( $title ) ), + 'asserts object instances are of type singleton' + ); + + $prototype = $instance->setScope( DependencyObject::SCOPE_PROTOTYPE )->newObject( 'Scope', array( $title ) ); + + $this->assertFalse( + $prototype === $instance->newObject( 'Scope', array( $title ) ), + 'asserts object scope definition were temporarily altered using setScope()' + ); + + $newSingleton = $instance->newObject( 'Scope', array( $title ) ); + + $this->assertTrue( + $newSingleton === $instance->newObject( 'Scope', array( $title ) ), + 'asserts original object scope has been restored' + ); + + $this->assertTrue( + $newSingleton === $instance->newObject( 'Scope', array( $title ) ), + 'asserts original object scope has been restored' + ); + + $this->assertTrue( + $newSingleton === $singleton, + 'asserts original object scope has been restored' + ); + + } + + /** + * @since 1.9 + */ + public function testSetScope() { + + $instance = $this->newInstance(); + + $instance->getContainer()->registerObject( 'Scope', function() { return new Title(); }, + DependencyObject::SCOPE_SINGLETON ); + + $this->assertTrue( + $instance->Scope() === $instance->Scope(), + 'asserts object instances are of type singleton' + ); + + $instance->getContainer()->registerObject( 'Scope', function() { return new Title(); }, + DependencyObject::SCOPE_PROTOTYPE ); + + $this->assertFalse( + $instance->Scope() === $instance->newObject( 'Scope' ), + 'asserts object instances are of type prototype' + ); + + $this->assertFalse( + $instance->setScope( DependencyObject::SCOPE_SINGLETON )->Scope() === $instance->newObject( 'Scope' ), + 'asserts object instances are different' + ); + + $this->assertTrue( + $instance->setScope( DependencyObject::SCOPE_SINGLETON )->Scope() === + $instance->setScope( DependencyObject::SCOPE_SINGLETON )->newObject( 'Scope' ), + 'asserts object instances are of type singleton' + ); + + } + + /** + * @since 1.9 + */ + public function testSetCall() { + + $instance = $this->newInstance(); + $title = $this->newTitle( NS_MAIN, 'Lula' ); + + $instance->getContainer()->FakeWikiPage = function( DependencyBuilder $builder ) { + return FakeWikiPage::newFromTitle( $builder->getArgument( 'Title' ) ); + }; + + $this->assertInstanceOf( + 'Title', + $instance->FakeWikiPage( $title )->getTitle(), + 'asserts that ...' + ); + + } + + /** + * @since 1.9 + */ + public function testSetCallMultipleArguments() { + + $instance = $this->newInstance(); + $title1 = $this->newTitle( NS_MAIN, 'Lula' ); + $title2 = $this->newTitle( NS_MAIN, 'Lila' ); + + $instance->getContainer()->getArray = function( DependencyBuilder $builder ) { + return array( $builder->getArgument( 'Title1' ), $builder->getArgument( 'Title2' ) ); + }; + + $this->assertEquals( + array( $title1, $title2 ), + $instance->addArgument( 'Title1', $title1 )->addArgument( 'Title2', $title2 )->getArray(), + 'asserts that ...' + ); + + $this->assertEquals( + array( $title1, $title2 ), + $instance->getArray( array( + 'Title1' => $title1, + 'Title2' => $title2 + ) ), + 'asserts that ...' + ); + + } + + /** + * @dataProvider scopeDataProvider + * + * @since 1.9 + */ + public function testSetCallMagicWordScope( $setup, $expected ) { + + $instance = $this->newInstance(); + $scope = $this->getScopeDefinition( $setup['scope'] ); + $title = $this->newTitle( NS_MAIN, 'Lula' ); + + $instance->getContainer()->FakeWikiPage = function() use( $title ) { + return new FakeWikiPage( $title ); + }; + + $this->assertFalse( + $instance->FakeWikiPage() === $instance->newObject( 'FakeWikiPage' ), + 'asserts that __set/__call itself are always of type SCOPE_PROTOTYPE' + ); + + // If __set/__call is embedded in a SCOPE_SINGLETON call which makes indirectly available + // through the SINGLETON as it is only executed once during initialization + $instance->getContainer()->registerObject( 'a1234', function( $builder ) { + return $builder->FakeWikiPage(); + }, $scope ); + + $this->assertEquals( + $expected, + $instance->newObject( 'a1234' ) === $instance->a1234(), + 'asserts whether instances are equal to the selected scope' + ); + + } + + /** + * @since 1.9 + */ + public function testRegisterObjectAndRemove() { + + $instance = $this->newInstance(); + + $this->assertFalse( + $instance->getContainer()->has( 'Title' ), + 'asserts that the container does not have a particular object definition' + ); + + $instance->getContainer()->registerObject( 'Title', $this->newMockBuilder()->newObject( 'Title' ) ); + + $this->assertTrue( + $instance->getContainer()->has( 'Title' ), + 'asserts that after registration the container has a particular object definition' + ); + + $instance->getContainer()->remove( 'Title' ); + + $this->assertFalse( + $instance->getContainer()->has( 'Title' ), + 'asserts that after removal the container does not have a particular object definition' + ); + + } + + /** + * @dataProvider dependencyObjectDataProvider + * + * @since 1.9 + */ + public function testDeferredLoading( $setup, $expected ) { + + $container = $this->newMockBuilder()->newObject( 'FakeDependencyContainer', array( + 'getDefinitions' => array( 'Quux' => $setup ) + ) ); + + $instance = $this->newInstance( $container ); + + $this->assertEquals( + $expected, + $instance->newObject( 'Quux' ), + 'asserts whether object was registered and accessible' + ); + + } + + /** + * A object definition depends on previous definitions in order to build a + * requested object instance + * + * @since 1.9 + */ + public function testDeferredLoadingWithScopeChangeAndRecursiveObjectGraph() { + + $objectGraph = array( + + 'Title' => function( $builder ) { + return new Title(); + }, + + 'FakeWikiPage' => function( $builder ) { + return new FakeWikiPage( $builder->newObject( 'Title' ) ); + }, + + 'Bar' => function( $builder ) { + return $builder->newObject( 'FakeWikiPage' ); + }, + + 'Quux' => function( $builder ) { + return $builder->newObject( 'Bar' ); + } + + ); + + $container = $this->newMockBuilder()->newObject( 'FakeDependencyContainer', array( + 'getDefinitions' => $objectGraph + ) ); + + $instance = $this->newInstance( $container ); + + $iQuux = $instance->setScope( DependencyObject::SCOPE_SINGLETON )->newObject( 'Quux' ); + + $this->assertTrue( + $iQuux->getTitle() === $instance->setScope( DependencyObject::SCOPE_SINGLETON )->newObject( 'Quux' )->getTitle(), + 'Asserts that the scope was altered despite its original definition' + ); + + $this->assertFalse( + $iQuux->getTitle() === $instance->newObject( 'Quux' )->getTitle(), + 'Asserts that the original scope definition has been restored' + ); + + } + + + /** + * @since 1.9 + */ + public function testGetArgumentOutOfBoundsException() { + + $this->setExpectedException( 'OutOfBoundsException' ); + $this->newInstance()->getArgument( 'Title' ); + + } + + /** + * @since 1.9 + */ + public function testHasArgumentInvalidArgument() { + + $this->setExpectedException( 'InvalidArgumentException' ); + $this->newInstance()->hasArgument( 9001 ); + + } + + /** + * @since 1.9 + */ + public function testAddArgumentInvalidArgument() { + + $this->setExpectedException( 'InvalidArgumentException' ); + $this->newInstance()->addArgument( $this->newTitle(), 'Title' ); + + } + + /** + * @since 1.9 + */ + public function testNewObjectInvalidArgument() { + + $this->setExpectedException( 'InvalidArgumentException' ); + $this->newInstance()->newObject( new \stdclass ); + + } + + /** + * @since 1.9 + */ + public function testNewObjectArgumentsInvalidArgument() { + + $this->setExpectedException( 'InvalidArgumentException' ); + $this->newInstance()->newObject( 'Test', new \stdclass ); + + } + + /** + * @since 1.9 + */ + public function testNewObjectUnknownObject() { + + $this->setExpectedException( 'OutOfBoundsException' ); + $this->newInstance()->newObject( 'Foo' ); + + } + + /** + * @since 1.9 + */ + public function testNewObjectDeferredLoadingUnknownObject() { + + $this->setExpectedException( 'OutOfBoundsException' ); + $instance = $this->newInstance(); + $instance->getContainer()->registerObject( 'DiObjectMapper', array( 'Title' => 'Title' ) ); + $instance->newObject( 'Title' ); + + $this->assertTrue( true ); + } + + /** + * @since 1.9 + */ + public function testSingletonCircularReferenceDetectionOutOfBoundsException() { + + $this->setExpectedException( 'OutOfBoundsException' ); + + $instance = $this->newInstance(); + $instance->getContainer()->registerObject( 'Foo', function( $builder ) { + return $builder->newObject( 'Foo' ); + }, DependencyObject::SCOPE_SINGLETON ); + + $instance->newObject( 'Foo' ); + + } + + /** + * @since 1.9 + */ + public function testPrototypeCircularReferenceDetectionOutOfBoundsException() { + + $this->setExpectedException( 'OutOfBoundsException' ); + + $instance = $this->newInstance(); + $instance->getContainer()->registerObject( 'Bar', function( $builder ) { + return $builder->newObject( 'Bar' ); + }, DependencyObject::SCOPE_PROTOTYPE ); + + $instance->newObject( 'Foo' ); + + } + + /** + * @since 1.9 + */ + public function testDeferredPrototypeCircularReferenceDetectionOutOfBoundsException() { + + $this->setExpectedException( 'OutOfBoundsException' ); + + $objectGraph = array( + + 'Title' => function( $builder ) { + return $builder->newObject( 'Title' ); // self-reference + }, + + 'FakeWikiPage' => function( $builder ) { + return new FakeWikiPage( $builder->newObject( 'Title' ) ); + }, + + 'Bar' => function( $builder ) { + return $builder->newObject( 'FakeWikiPage' ); + }, + + 'Foo' => function( $builder ) { + return $builder->newObject( 'Bar' ); + }, + + 'Quux' => function( $builder ) { + return $builder->newObject( 'Foo' ); + } + + ); + + $container = $this->newMockBuilder()->newObject( 'FakeDependencyContainer', array( + 'getDefinitions' => $objectGraph + ) ); + + $instance = $this->newInstance( $container ); + $instance->newObject( 'Quux' ); + + } + + /** + * @return array + */ + public function scopeDataProvider() { + + $provider = array(); + + $provider[] = array( array( 'scope' => 'SCOPE_SINGLETON' ), true ); + + // Inverse behaviour to the previous assert + $provider[] = array( array( 'scope' => 'SCOPE_PROTOTYPE' ), false ); + + return $provider; + } + + /** + * @return array + */ + public function autoArgumentsDataProvider() { + + $provider = array(); + $title = $this->newTitle( NS_MAIN, 'Lala' ); + + $provider[] = array( array( $title ), $title ); + $provider[] = array( array( $title, $title ), $title ); + $provider[] = array( array( 'Title' => $title, 'Title2' => $title ), $title ); + + return $provider; + } + + /** + * @return array + */ + public function dependencyObjectDataProvider() { + + $provider = array(); + + $stdClass = new \stdClass; + $closure = function() use( $stdClass ) { return $stdClass; }; + + // #0 + $dependencyObject = $this->newMockBuilder()->newObject( 'DependencyObject', array( + 'retrieveDefinition' => $stdClass + ) ); + + $provider[] = array( $dependencyObject, $stdClass ); + + // #1 + $dependencyObject = $this->newMockBuilder()->newObject( 'DependencyObject', array( + 'retrieveDefinition' => $closure + ) ); + + $provider[] = array( $dependencyObject, $stdClass ); + + // #3 + $provider[] = array( $closure, $stdClass ); + + // #4 + $provider[] = array( 'stdClass', $stdClass ); + + return $provider; + } + +} + + +/** + * A fake object instance + */ +class FakeWikiPage { + + protected $title = null; + + public function __construct( Title $title ) { + $this->title = $title; + } + + public static function newFromTitle( Title $title ) { + return new self( $title ); + } + + public function getTitle() { + return $this->title; + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/export/ExportSemanticDataTest.php b/SemanticMediaWiki/tests/phpunit/includes/export/ExportSemanticDataTest.php new file mode 100644 index 00000000..97f60e0a --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/export/ExportSemanticDataTest.php @@ -0,0 +1,314 @@ +<?php + +namespace SMW\Tests\Export; + +use SMW\Tests\Util\SemanticDataFactory; +use SMW\Tests\Util\ExportDataValidator; + +use SMW\DIWikiPage; +use SMW\DIProperty; +use SMW\DataValueFactory; +use SMW\Subobject; + +use SMWExporter as Exporter; +use SMWExpNsResource as ExpNsResource; +use SMWExpResource as ExpResource; + +/** + * @covers \SMWExporter + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class ExportSemanticDataTest extends \PHPUnit_Framework_TestCase { + + private $semanticDataFactory; + private $dataValueFactory; + private $exportDataValidator; + + protected function setUp() { + parent::setUp(); + + $this->dataValueFactory = DataValueFactory::getInstance(); + $this->semanticDataFactory = new SemanticDataFactory(); + $this->exportDataValidator = new ExportDataValidator(); + } + + public function testExportRedirect() { + + $semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ ); + + $redirectProperty = new DIProperty( '_REDI' ); + $redirectTarget = new DIWikiPage( 'FooRedirectTarget', NS_MAIN, '' ); + + $semanticData->addPropertyObjectValue( + $redirectProperty, + DIWikiPage::newFromTitle( $redirectTarget->getTitle(), '__red' ) + ); + + $exportData = Exporter::makeExportData( $semanticData ); + + $this->assertCount( + 1, + $exportData->getValues( Exporter::getSpecialNsResource( 'swivt', 'redirectsTo' ) ) + ); + + $this->assertCount( + 1, + $exportData->getValues( Exporter::getSpecialNsResource( 'owl', 'sameAs' ) ) + ); + + $expectedResourceElement = new ExpNsResource( + 'FooRedirectTarget', + Exporter::getNamespaceUri( 'wiki' ), + 'wiki', + $redirectTarget + ); + + $this->exportDataValidator->assertThatExportDataContainsResource( + $expectedResourceElement, + Exporter::getSpecialNsResource( 'owl', 'sameAs' ), + $exportData + ); + } + + public function testExportPageWithNumericProperty() { + + $semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ ); + + $property = new DIProperty( '123' ); + + $semanticData->addPropertyObjectValue( + $property, + new DIWikiPage( '345', NS_MAIN ) + ); + + $exportData = Exporter::makeExportData( $semanticData ); + + $expectedProperty = new ExpNsResource( + Exporter::getInstance()->getEncodedPropertyNamespace() . '123', + Exporter::getNamespaceUri( 'wiki' ), + 'wiki', + new DIWikiPage( '123', SMW_NS_PROPERTY ) + ); + + $this->assertCount( + 1, + $exportData->getValues( $expectedProperty ) + ); + + $this->exportDataValidator->assertThatExportDataContainsProperty( + $expectedProperty, + $exportData + ); + + $expectedResourceElement = new ExpNsResource( + '345', + Exporter::getNamespaceUri( 'wiki' ), + 'wiki', + new DIWikiPage( '345', NS_MAIN ) + ); + + $this->exportDataValidator->assertThatExportDataContainsResource( + $expectedResourceElement, + $expectedProperty, + $exportData + ); + } + + public function testExportPageWithNonNumericProperty() { + + $semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ ); + + $property = new DIProperty( 'A123' ); + + $semanticData->addPropertyObjectValue( + $property, + new DIWikiPage( '345', NS_MAIN ) + ); + + $exportData = Exporter::makeExportData( $semanticData ); + + $expectedProperty = new ExpNsResource( + 'A123', + Exporter::getNamespaceUri( 'property' ), + 'property', + new DIWikiPage( 'A123', SMW_NS_PROPERTY ) + ); + + $this->assertCount( + 1, + $exportData->getValues( $expectedProperty ) + ); + + $this->exportDataValidator->assertThatExportDataContainsProperty( + $expectedProperty, + $exportData + ); + + $expectedResource = new ExpNsResource( + '345', + Exporter::getNamespaceUri( 'wiki' ), + 'wiki', + new DIWikiPage( '345', NS_MAIN ) + ); + + $this->exportDataValidator->assertThatExportDataContainsResource( + $expectedResource, + $expectedProperty, + $exportData + ); + } + + public function testExportSubproperty() { + + $semanticData = $this->semanticDataFactory + ->setSubject( new DIWikiPage( 'SomeSubproperty', SMW_NS_PROPERTY ) ) + ->newEmptySemanticData(); + + $semanticData->addDataValue( + $this->dataValueFactory->newPropertyObjectValue( new DIProperty( '_SUBP' ), 'SomeTopProperty' ) + ); + + $exportData = Exporter::makeExportData( $semanticData ); + + $this->assertCount( + 1, + $exportData->getValues( Exporter::getSpecialNsResource( 'rdfs', 'subPropertyOf' ) ) + ); + + $expectedResourceElement = new ExpNsResource( + 'SomeTopProperty', + Exporter::getNamespaceUri( 'property' ), + 'property', + new DIWikiPage( 'SomeTopProperty', SMW_NS_PROPERTY ) + ); + + $this->exportDataValidator->assertThatExportDataContainsResource( + $expectedResourceElement, + Exporter::getSpecialNsResource( 'rdfs', 'subPropertyOf' ), + $exportData + ); + } + + public function testExportCategory() { + + $semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ ); + + $semanticData->addDataValue( + $this->dataValueFactory->newPropertyObjectValue( new DIProperty( '_INST' ), 'SomeCategory' ) + ); + + $exportData = Exporter::makeExportData( $semanticData ); + + $this->assertCount( + 2, + $exportData->getValues( Exporter::getSpecialNsResource( 'rdf', 'type' ) ) + ); + + $expectedResourceElement = new ExpNsResource( + Exporter::getEncodedPageName( new DIWikiPage( 'SomeCategory', NS_CATEGORY ) ), + Exporter::getNamespaceUri( 'wiki' ), + 'wiki', + new DIWikiPage( 'SomeCategory', NS_CATEGORY ) + ); + + $this->exportDataValidator->assertThatExportDataContainsResource( + $expectedResourceElement, + Exporter::getSpecialNsResource( 'rdf', 'type' ), + $exportData + ); + } + + public function testExportSubcategory() { + + $semanticData = $this->semanticDataFactory + ->setSubject( new DIWikiPage( 'SomeSubcategory', NS_CATEGORY ) ) + ->newEmptySemanticData(); + + $semanticData->addDataValue( + $this->dataValueFactory->newPropertyObjectValue( new DIProperty( '_SUBC' ), 'SomeTopCategory' ) + ); + + $exportData = Exporter::makeExportData( $semanticData ); + + $this->assertCount( + 1, + $exportData->getValues( Exporter::getSpecialNsResource( 'rdfs', 'subClassOf' ) ) + ); + + $expectedResourceElement = new ExpNsResource( + Exporter::getEncodedPageName( new DIWikiPage( 'SomeTopCategory', NS_CATEGORY ) ), + Exporter::getNamespaceUri( 'wiki' ), + 'wiki', + new DIWikiPage( 'SomeTopCategory', NS_CATEGORY ) + ); + + $this->exportDataValidator->assertThatExportDataContainsResource( + $expectedResourceElement, + Exporter::getSpecialNsResource( 'rdfs', 'subClassOf' ), + $exportData + ); + } + + public function testExportSubobject() { + + $semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ ); + + $subobject = new Subobject( $semanticData->getSubject()->getTitle() ); + $subobject->setEmptySemanticDataforId( 'Foo' ); + + $semanticData->addPropertyObjectValue( + $subobject->getProperty(), + $subobject->getContainer() + ); + + $exportData = Exporter::makeExportData( $semanticData ); + + $expectedProperty = new ExpNsResource( + $this->transformPropertyLabelToAuxiliary( $subobject->getProperty() ), + Exporter::getNamespaceUri( 'property' ), + 'property', + new DIWikiPage( 'Has_subobject', SMW_NS_PROPERTY ) + ); + + $this->assertTrue( + Exporter::hasHelperExpElement( $subobject->getProperty() ) + ); + + $this->assertCount( + 1, + $exportData->getValues( $expectedProperty ) + ); + + $this->exportDataValidator->assertThatExportDataContainsProperty( + $expectedProperty, + $exportData + ); + + $expectedResource = new ExpNsResource( + Exporter::getEncodedPageName( $subobject->getSemanticData()->getSubject() ) . '-23' . 'Foo', + Exporter::getNamespaceUri( 'wiki' ), + 'wiki', + $subobject->getSemanticData()->getSubject() + ); + + $this->exportDataValidator->assertThatExportDataContainsResource( + $expectedResource, + $expectedProperty, + $exportData + ); + } + + private function transformPropertyLabelToAuxiliary( DIProperty $property ) { + return str_replace( ' ', '_', $property->getLabel() ) . '-23' . 'aux'; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/export/SMWExpElementTest.php b/SemanticMediaWiki/tests/phpunit/includes/export/SMWExpElementTest.php new file mode 100644 index 00000000..7e10e2b8 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/export/SMWExpElementTest.php @@ -0,0 +1,170 @@ +<?php + +namespace SMW\Tests; + +/** + * Tests for the SMWExpElement deriving classes. + * + * @file + * @since 1.9 + * + * @ingroup SMW + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class SMWExpElementTest extends \PHPUnit_Framework_TestCase { + + public function instanceProvider() { + $instances = array(); + + $instances[] = new \SMWExpResource( 'foo' ); + $instances[] = new \SMWExpResource( 'foo', null ); + $instances[] = new \SMWExpResource( 'foo', new \SMWDIBlob( 'bar' ) ); + + $instances[] = new \SMWExpNsResource( 'foo', 'bar', 'baz' ); + $instances[] = new \SMWExpNsResource( 'foo', 'bar', 'baz', null ); + $instances[] = new \SMWExpNsResource( 'foo', 'bar', 'baz', new \SMWDIBlob( 'bar' ) ); + + $instances[] = new \SMWExpLiteral( 'foo' ); + $instances[] = new \SMWExpLiteral( 'foo', '' ); + $instances[] = new \SMWExpLiteral( 'foo', 'bar' ); + $instances[] = new \SMWExpLiteral( 'foo', '', null ); + $instances[] = new \SMWExpLiteral( 'foo', '', new \SMWDIBlob( 'bar' ) ); + $instances[] = new \SMWExpLiteral( 'foo', 'baz', new \SMWDIBlob( 'bar' ) ); + + return $this->arrayWrap( $instances ); + } + + /** + * @dataProvider instanceProvider + */ + public function testGetDataItem( \SMWExpElement $element ) { + $this->assertTypeOrValue( 'SMWDataItem', $element->getDataItem(), null ); + } + + /** + * @dataProvider instanceProvider + */ + public function testGetLexicalForm( \SMWExpElement $element ) { + if ( method_exists( $element, 'getLexicalForm' ) ) { + $this->assertType( 'string', $element->getLexicalForm() ); + } + else { + $this->assertTrue( true ); + } + } + + /** + * @dataProvider instanceProvider + */ + public function testGetDatatype( \SMWExpElement $element ) { + if ( method_exists( $element, 'getDatatype' ) ) { + $this->assertType( 'string', $element->getDatatype() ); + } + else { + $this->assertTrue( true ); + } + } + + /** + * @dataProvider instanceProvider + */ + public function testGetLocalName( \SMWExpElement $element ) { + if ( method_exists( $element, 'getLocalName' ) ) { + $this->assertType( 'string', $element->getLocalName() ); + } + else { + $this->assertTrue( true ); + } + } + + /** + * @dataProvider instanceProvider + */ + public function testgetNamespace( \SMWExpElement $element ) { + if ( method_exists( $element, 'getNamespace' ) ) { + $this->assertType( 'string', $element->getNamespace() ); + } + else { + $this->assertTrue( true ); + } + } + + /** + * @dataProvider instanceProvider + */ + public function testGetNamespaceId( \SMWExpElement $element ) { + if ( method_exists( $element, 'getNamespaceId' ) ) { + $this->assertType( 'string', $element->getNamespaceId() ); + } + else { + $this->assertTrue( true ); + } + } + + /** + * @dataProvider instanceProvider + */ + public function testGetQName( \SMWExpElement $element ) { + if ( method_exists( $element, 'getQName' ) ) { + $this->assertType( 'string', $element->getQName() ); + } + else { + $this->assertTrue( true ); + } + } + + /** + * @dataProvider instanceProvider + */ + public function testGetUri( \SMWExpElement $element ) { + if ( method_exists( $element, 'getUri' ) ) { + $this->assertType( 'string', $element->getUri() ); + } + else { + $this->assertTrue( true ); + } + } + /** + * @dataProvider instanceProvider + */ + public function testIsBlankNode( \SMWExpElement $element ) { + if ( method_exists( $element, 'isBlankNode' ) ) { + $this->assertType( 'boolean', $element->isBlankNode() ); + } + else { + $this->assertTrue( true ); + } + } + + protected function arrayWrap( array $elements ) { + return array_map( + function ( $element ) { + return array( $element ); + }, + $elements + ); + } + + protected function assertTypeOrValue( $type, $actual, $value = false, $message = '' ) { + if ( $actual === $value ) { + $this->assertTrue( true, $message ); + } else { + $this->assertType( $type, $actual, $message ); + } + } + + protected function assertType( $type, $actual, $message = '' ) { + if ( class_exists( $type ) || interface_exists( $type ) ) { + $this->assertInstanceOf( $type, $actual, $message ); + } else { + $this->assertInternalType( $type, $actual, $message ); + } + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/export/SMWExporterTest.php b/SemanticMediaWiki/tests/phpunit/includes/export/SMWExporterTest.php new file mode 100644 index 00000000..47bd2832 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/export/SMWExporterTest.php @@ -0,0 +1,84 @@ +<?php + +namespace SMW\Tests; + +use SMW\DIWikiPage; + +use SMWDataItem as DataItem; +use SMWDINumber as DINumber; +use SMWDIBlob as DIBlob; +use SMWDIBoolean as DIBoolean; +use SMWDIConcept as DIConcept; + +use SMWExporter as Exporter; +use SMWExpResource as ExpResource; + +/** + * @covers \SMWExporter + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SMWExporterTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider dataItemExpElementProvider + */ + public function testGetDataItemExpElement( DataItem $dataItem, $instance ) { + + if ( $instance === null ) { + return $this->assertNull( Exporter::getDataItemExpElement( $dataItem ) ); + } + + $this->assertInstanceOf( $instance, Exporter::getDataItemExpElement( $dataItem ) ); + } + + /** + * @dataProvider uriDataItemProvider + * #378 + */ + public function testFindDataItemForExpElement( $uri, $expectedDataItem ) { + + $uri = Exporter::getNamespaceUri( 'wiki' ) . $uri; + + $this->assertEquals( + $expectedDataItem, + Exporter::findDataItemForExpElement( new ExpResource( $uri ) ) + ); + } + + public function dataItemExpElementProvider() { + + // #0 (bug 56643) + $provider[] = array( new DINumber( 9001 ), 'SMWExpElement' ); + + $provider[] = array( new DIBlob( 'foo' ), 'SMWExpElement' ); + $provider[] = array( new DIBoolean( true ), 'SMWExpElement' ); + + $provider[] = array( new DIConcept( 'Foo', '', '', '', '' ), null ); + + return $provider; + } + + public function uriDataItemProvider() { + + $provider[] = array( 'Foo', new DIWikiPage( 'Foo', NS_MAIN, '', '' ) ); + $provider[] = array( 'Foo#Bar', new DIWikiPage( 'Foo', NS_MAIN, '', 'Bar' ) ); + $provider[] = array( 'Foo#Bar#Oooo', new DIWikiPage( 'Foo', NS_MAIN, '', 'Bar#Oooo' ) ); + $provider[] = array( 'Property:Foo', new DIWikiPage( 'Foo', SMW_NS_PROPERTY, '', '' ) ); + $provider[] = array( 'Concept:Foo', new DIWikiPage( 'Foo', SMW_NS_CONCEPT, '', '' ) ); + $provider[] = array( 'Unknown:Foo', new DIWikiPage( 'Unknown:Foo', NS_MAIN, '', '' ) ); + $provider[] = array( 'Unknown:Foo#Bar', new DIWikiPage( 'Unknown:Foo', NS_MAIN, '', 'Bar' ) ); + $provider[] = array( 'Property:Foo#Bar', new DIWikiPage( 'Foo', SMW_NS_PROPERTY, '', 'Bar' ) ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/formatters/MessageFormatterTest.php b/SemanticMediaWiki/tests/phpunit/includes/formatters/MessageFormatterTest.php new file mode 100644 index 00000000..66a2832b --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/formatters/MessageFormatterTest.php @@ -0,0 +1,283 @@ +<?php + +namespace SMW\Test; + +use SMW\MessageFormatter; +use Message; +use ReflectionClass; + +/** + * Tests for the MessageFormatter class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\MessageFormatter + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class MessageFormatterTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string + */ + public function getClass() { + return '\SMW\MessageFormatter'; + } + + /** + * Helper method that returns an MessageFormatter instance + * + * @since 1.9 + * + * @return MessageFormatter + */ + private function getInstance() { + return new MessageFormatter( $this->getLanguage() ); + } + + /** + * @test MessageFormatter::__construct + * @dataProvider getDataProvider + * + * @since 1.9 + */ + public function testConstructor() { + $instance = $this->getInstance(); + $this->assertInstanceOf( $this->getClass(), $instance ); + } + + /** + * @test MessageFormatter::newFromArray + * @test MessageFormatter::setType + * @test MessageFormatter::getHtml + * @dataProvider getDataProvider + * + * @since 1.9 + * + * @param array $messages + */ + public function testNewFromArray( array $messages ) { + $instance = MessageFormatter::newFromArray( + $this->getLanguage(), + $messages + ); + + $instance->setType( 'error' ); + $this->assertInternalType( 'string', $instance->getHtml() ); + + $instance->setType( 'warning' ); + $this->assertInternalType( 'string', $instance->getHtml() ); + + $instance->setType( 'info' ); + $this->assertInternalType( 'string', $instance->getHtml() ); + + } + + /** + * @test MessageFormatter::addFromKey + * @test MessageFormatter::getMessages + * + * @since 1.9 + */ + public function testAddFromKey() { + $instance = $this->getInstance(); + $param = '1001'; + + $instance->addFromKey( 'Foo', $param ) + ->addFromKey( 'Bar', $param ) + ->addFromKey( 'Foo', $param ); + + $messages = $instance->getMessages(); + + // Returns count of existing with duplicates, elimination is + // applied only during output (getHtml/getPlain) + $this->assertCount( 3, $messages ); + + foreach ( $messages as $msg ) { + $this->assertInstanceOf( '\Message', $msg ); + + // getParams() only got added in MW 1.21 + if ( method_exists( $msg, 'getParams' ) ) { + foreach ( $msg->getParams() as $result ) { + $this->assertEquals( $param, $result ); + } + } + } + } + + /** + * @test MessageFormatter::setLanguage + * @test MessageFormatter::getPlain + * + * @since 1.9 + */ + public function testSetLanguage() { + $key = 'properties'; + $msg = new Message( $key ); + $instance = $this->getInstance(); + + $instance->addFromKey( $key ); + $instance->setLanguage( $this->getLanguage( 'zh-tw' ) ); + + $this->assertEquals( + $msg->inLanguage( $this->getLanguage( 'zh-tw' ) )->text(), + $instance->getPlain() + ); + + $instance->clear(); + $this->assertEmpty( $instance->getPlain() ); + + } + + /** + * @test MessageFormatter::format + * @dataProvider getDataProvider + * + * @since 1.9 + * + * @param array $messages + * @param integer $count + */ + public function testFormat( array $messages, $count ) { + $instance = $this->getInstance(); + $instance->addFromArray( $messages ); + + // Access protected method + $reflection = new ReflectionClass( $this->getClass() ); + $method = $reflection->getMethod( 'doFormat' ); + $method->setAccessible( true ); + + // Test array normalization and deletion of duplicates + $result = $method->invoke( $instance, $instance->getMessages() ); + $this->assertCount( $count, $result ); + + } + + /** + * @test MessageFormatter::getHtml + * @dataProvider getDataProvider + * + * @since 1.9 + * + * @param array $messages + */ + public function testGetHtml( array $messages ) { + $instance = $this->getInstance(); + $instance->addFromArray( $messages ); + + $this->assertInternalType( 'string', $instance->getHtml() ); + } + + /** + * @test MessageFormatter::getPlain + * @dataProvider getDataProvider + * + * @since 1.9 + * + * @param array $messages + */ + public function testGetPlain( array $messages ) { + $instance = $this->getInstance(); + $instance->addFromArray( $messages ); + + $this->assertInternalType( 'string', $instance->getPlain() ); + } + + /** + * @test MessageFormatter::escape + * @test MessageFormatter::getPlain + * + * @since 1.9 + */ + public function testEscapedUnescaped() { + $instance = $this->getInstance(); + $instance->addFromArray( array( '<Foo>' ) ); + + $this->assertEquals( '<Foo>', $instance->escape( true )->getPlain() ); + $this->assertEquals( '<Foo>', $instance->escape( false )->getPlain() ); + + } + + /** + * Message from different sources could have different depth therefore + * objects need to be resolved recursively in order to ensure a 1-n array + * + */ + public function getDataProvider() { + return array( + + // #0 Empty array + array( array(), 0 ), + + // #1 Simple string elements 5 elements (one duplicate) = 4 + array( + array( + 'Foo', 'Bar', array( 'FooBar', array( 'barFoo', 'Foo' ) ) + ), + 4 + ), + + // #2 A duplicate Message object = 1 + array( + array( + new Message( 'smw_iq_disabled' ), + new Message( 'smw_iq_disabled' ) + ), + 1 + ), + + // #3 Different Message objects + array( + array( + new Message( 'smw_iq_disabled' ), + new Message( 'smw_multiple_concepts' ) + ), + 2 + ), + + // #4 Invoked MessageFormatter object (recursive test) + array( + array( + new Message( 'smw_iq_disabled' ), + array( new Message( 'smw_iq_disabled' ), + new Message( 'smw_multiple_concepts' ) + ) + ), + 2 + ), + + // #5 Combine different objects (recursive test) containing 7 messages + // where two of them are duplicates resulting in 5 objects + array( + array( + new Message( 'smw_iq_disabled' ), + new Message( 'smw_multiple_concepts' ), + array( + new Message( 'smw_iq_disabled' ), + 'Foo' + ), + array( + array( + new Message( 'smw_no_concept_namespace' ), + new Message( 'foo' ), + 'Foo' + ) + ) + ), + 5 + ), + ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/formatters/ParameterFormatterFactoryTest.php b/SemanticMediaWiki/tests/phpunit/includes/formatters/ParameterFormatterFactoryTest.php new file mode 100644 index 00000000..0e84d0f1 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/formatters/ParameterFormatterFactoryTest.php @@ -0,0 +1,73 @@ +<?php + +namespace SMW\Test; + +use SMW\ParameterFormatterFactory; + +/** + * Tests for the ParameterFormatterFactory class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\ParameterFormatterFactory + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class ParameterFormatterFactoryTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\ParameterFormatterFactory'; + } + + /** + * Helper method that returns a ArrayFormatter object + * + * @since 1.9 + * + * @param array $params + * + * @return ArrayFormatter + */ + private function getInstance( array $params = array() ) { + return ParameterFormatterFactory::newFromArray( $params ); + } + + /** + * @test ParameterFormatterFactory::newFromArray + * + * @since 1.9 + */ + public function testNewFromArray() { + + // Object + $parameter = array( new \stdClass ); + $instance = $this->getInstance( $parameter ); + + $this->assertInstanceOf( '\SMW\ArrayFormatter', $instance ); + $this->assertEmpty( $instance->getRaw() ); + + // Simple array + $parameter = array( 'La' => 'Lu' ); + $instance = $this->getInstance( $parameter ); + + $this->assertInstanceOf( '\SMW\ArrayFormatter', $instance ); + $this->assertEquals( $parameter, $instance->getRaw() ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/formatters/ParserParameterFormatterTest.php b/SemanticMediaWiki/tests/phpunit/includes/formatters/ParserParameterFormatterTest.php new file mode 100644 index 00000000..90d44fa2 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/formatters/ParserParameterFormatterTest.php @@ -0,0 +1,335 @@ +<?php + +namespace SMW\Test; + +use SMW\ParserParameterFormatter; + +/** + * Tests for the ParserParameterFormatter class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\ParserParameterFormatter + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class ParserParameterFormatterTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\ParserParameterFormatter'; + } + + /** + * Helper method that returns a ParserParameterFormatter object + * + * @since 1.9 + * + * @param array $params + * + * @return ParserParameterFormatter + */ + private function getInstance( array $params ) { + return new ParserParameterFormatter( $params ); + } + + /** + * @test ParserParameterFormatter::__construct + * @dataProvider getParametersDataProvider + * + * @since 1.9 + * + * @param array $params + */ + public function testConstructor( array $params ) { + $instance = $this->getInstance( $params ); + $this->assertInstanceOf( 'SMW\ParserParameterFormatter', $instance ); + } + + /** + * @test ParserParameterFormatter::getRaw + * @dataProvider getParametersDataProvider + * + * @since 1.9 + * + * @param array $params + */ + public function testGetRaw( array $params ) { + $instance = $this->getInstance( $params ); + $this->assertEquals( $params, $instance->getRaw() ); + } + + /** + * @test ParserParameterFormatter::setParameters + * + * @since 1.9 + */ + public function testSetParameters() { + $instance = $this->getInstance( array() ); + $parameters = array( 'Foo' => 'Bar' ); + + $instance->setParameters( $parameters ); + $this->assertEquals( $parameters, $instance->toArray() ); + } + + /** + * @test ParserParameterFormatter::addParameter + * + * @since 1.9 + */ + public function testAddParameter() { + $instance = $this->getInstance( array() ); + $instance->addParameter( 'Foo', 'Bar' ); + + $this->assertEquals( array( 'Foo' =>array( 'Bar' ) ), $instance->toArray() ); + } + + /** + * @test ParserParameterFormatter::__construct (Test instance exception) + * @dataProvider getParametersDataProvider + * + * @since 1.9 + * + * @param array $params + */ + public function testConstructorException( array $params ) { + $this->setExpectedException( 'PHPUnit_Framework_Error' ); + $instance = $this->getInstance(); + } + + /** + * @test ParserParameterFormatter::toArray + * @dataProvider getParametersDataProvider + * + * @since 1.9 + * + * @param array $params + * @param array $expected + */ + public function testToArray( array $params, array $expected ) { + $instance = $this->getInstance( $params ); + $results = $instance->toArray(); + + $this->assertTrue( is_array( $results ) ); + $this->assertEquals( $expected, $results); + } + + /** + * @test ParserParameterFormatter::getFirst + * @dataProvider getFirstDataProvider + * + * @since 1.9 + * + * @param array $params + * @param array $expected + */ + public function testGetFirst( array $params, array $expected ) { + $results = $this->getInstance( $params ); + $this->assertEquals( $expected['identifier'], $results->getFirst() ); + } + + /** + * Provides sample data of parameter combinations + * + * @return array + */ + public function getParametersDataProvider() { + return array( + // {{#...: + // |Has test 1=One + // }} + array( + array( + 'Has test 1=One' + ), + array( + 'Has test 1' => array( 'One' ) + ) + ), + + // {{#...: + // |Has test 1=One + // }} + array( + array( + array( 'Foo' ), + 'Has test 1=One', + ), + array( + 'Has test 1' => array( 'One' ) + ), + array( + 'msg' => 'Failed to recognize that only strings can be processed' + ) + ), + + // {{#...: + // |Has test 2=Two + // |Has test 2=Three;Four|+sep=; + // }} + array( + array( + 'Has test 2=Two', + 'Has test 2=Three;Four', + '+sep=;' + ), + array( + 'Has test 2' => array( 'Two', 'Three', 'Four' ) + ) + ), + + // {{#...: + // |Has test 3=One,Two,Three|+sep + // |Has test 4=Four + // }} + array( + array( + 'Has test 3=One,Two,Three', + '+sep', + 'Has test 4=Four' + ), + array( + 'Has test 3' => array( 'One', 'Two', 'Three' ), + 'Has test 4' => array( 'Four' ) + ) + ), + + // {{#...: + // |Has test 5=Test 5-1|Test 5-2|Test 5-3|Test 5-4 + // |Has test 5=Test 5-5 + // }} + array( + array( + 'Has test 5=Test 5-1', + 'Test 5-2', + 'Test 5-3', + 'Test 5-4', + 'Has test 5=Test 5-5' + ), + array( + 'Has test 5' => array( 'Test 5-1', 'Test 5-2', 'Test 5-3', 'Test 5-4', 'Test 5-5' ) + ) + ), + + // {{#...: + // |Has test 6=1+2+3|+sep=+ + // |Has test 7=7 + // |Has test 8=9,10,11,|+sep= + // }} + array( + array( + 'Has test 6=1+2+3', + '+sep=+', + 'Has test 7=7', + 'Has test 8=9,10,11,', + '+sep=' + ), + array( + 'Has test 6' => array( '1', '2', '3'), + 'Has test 7' => array( '7' ), + 'Has test 8' => array( '9', '10', '11' ) + ) + ), + + // {{#...: + // |Has test 9=One,Two,Three|+sep=; + // |Has test 10=Four + // }} + array( + array( + 'Has test 9=One,Two,Three', + '+sep=;', + 'Has test 10=Four' + ), + array( + 'Has test 9' => array( 'One,Two,Three' ), + 'Has test 10' => array( 'Four' ) + ) + ), + + // {{#...: + // |Has test 11=Test 5-1|Test 5-2|Test 5-3|Test 5-4 + // |Has test 12=Test 5-5 + // |Has test 11=9,10,11,|+sep= + // }} + array( + array( + 'Has test 11=Test 5-1', + 'Test 5-2', + 'Test 5-3', + 'Test 5-4', + 'Has test 12=Test 5-5', + 'Has test 11=9,10,11,', + '+sep=' + ), + array( + 'Has test 11' => array( 'Test 5-1', 'Test 5-2', 'Test 5-3', 'Test 5-4', '9', '10', '11' ), + 'Has test 12' => array( 'Test 5-5' ) + ) + ), + + // {{#...: + // |Has test url=http://www.semantic-mediawiki.org/w/index.php?title=Subobject;http://www.semantic-mediawiki.org/w/index.php?title=Set|+sep=; + // }} + array( + array( + 'Has test url=http://www.semantic-mediawiki.org/w/index.php?title=Subobject;http://www.semantic-mediawiki.org/w/index.php?title=Set', + '+sep=;' + ), + array( + 'Has test url' => array( 'http://www.semantic-mediawiki.org/w/index.php?title=Subobject', 'http://www.semantic-mediawiki.org/w/index.php?title=Set' ) + ) + ), + + ); + } + + /** + * Provides sample data of first parameter combinations + * + * @return array + */ + public function getFirstDataProvider() { + return array( + // {{#subobject: + // |Has test 1=One + // }} + array( + array( '', 'Has test 1=One'), + array( 'identifier' => null ) + ), + + // {{#set_recurring_event:Foo + // |Has test 2=Two + // |Has test 2=Three;Four|+sep=; + // }} + array( + array( 'Foo' , 'Has test 2=Two', 'Has test 2=Three;Four', '+sep=;' ), + array( 'identifier' => 'Foo' ) + ), + + // {{#subobject:- + // |Has test 2=Two + // |Has test 2=Three;Four|+sep=; + // }} + array( + array( '-', 'Has test 2=Two', 'Has test 2=Three;Four', '+sep=;' ), + array( 'identifier' => '-' ) + ), + ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/formatters/TableFormatterTest.php b/SemanticMediaWiki/tests/phpunit/includes/formatters/TableFormatterTest.php new file mode 100644 index 00000000..55f1d2fa --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/formatters/TableFormatterTest.php @@ -0,0 +1,362 @@ +<?php + +namespace SMW\Test; + +use SMW\TableFormatter; + +use ReflectionClass; + +/** + * Tests for the TableFormatter class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\TableFormatter + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class TableFormatterTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\TableFormatter'; + } + + /** + * Helper method that returns a TableFormatter object + * + * @since 1.9 + * + * @param array $params + * + * @return TableFormatter + */ + private function getInstance( $htmlContext = false ) { + return new TableFormatter( $htmlContext ); + } + + /** + * @test TableFormatter::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $instance = $this->getInstance(); + $this->assertInstanceOf( $this->getClass(), $instance ); + } + + /** + * @test TableFormatter::addHeaderItem + * @test TableFormatter::getHeaderItems + * + * @since 1.9 + */ + public function testAddHeaderItem() { + $instance = $this->getInstance(); + $instance->addHeaderItem( 'span', 'lala' ); + + $matcher = array( 'tag' => 'span', 'content' => 'lala' ); + $this->assertTag( $matcher, $instance->getHeaderItems() ); + } + + /** + * @test TableFormatter::addTableHeader + * @test TableFormatter::getTableHeader + * + * @since 1.9 + */ + public function testAddTableHeader() { + + $instance = $this->getInstance(); + $instance->addTableHeader( 'lala' ); + $instance->getTable(); + + // Access protected method + $reflection = new ReflectionClass( $this->getClass() ); + $method = $reflection->getMethod( 'getTableHeader' ); + $method->setAccessible( true ); + + $matcher = array( 'tag' => 'th', 'content' => 'lala' ); + $this->assertTag( $matcher, $method->invoke( $instance ) ); + + // HTML context + $instance = $this->getInstance( true ); + $instance->addTableHeader( 'lila' ); + $instance->getTable(); + + // Access protected method + $reflection = new ReflectionClass( $this->getClass() ); + $method = $reflection->getMethod( 'getTableHeader' ); + $method->setAccessible( true ); + + $matcher = array( + 'tag' => 'thead', + 'child' => array( + 'tag' => 'th', + 'content' => 'lila' + ) + ); + + $this->assertTag( $matcher, $method->invoke( $instance ) ); + + } + + /** + * @test TableFormatter::addTableRow + * @test TableFormatter::addTableCell + * + * @since 1.9 + */ + public function testAddTableRow() { + + $instance = $this->getInstance(); + $instance->addTableCell( 'lala', array( 'class' => 'foo' ) ) + ->addTableRow() + ->addTableCell( 'lula' ) + ->addTableRow() + ->getTable(); + + // Access protected method + $reflection = new ReflectionClass( $this->getClass() ); + $method = $reflection->getMethod( 'getTableRows' ); + $method->setAccessible( true ); + + $matcher = array( + 'tag' => 'tr', + 'attributes' => array( 'class' => 'foo row-odd' ), + 'attributes' => array( 'class' => 'row-even' ), + 'descendant' => array( + 'tag' => 'td', + 'content' => 'lala' + ), + 'descendant' => array( + 'tag' => 'td', + 'content' => 'lula' + ) + ); + + $this->assertTag( $matcher, $method->invoke( $instance ) ); + + // HTML context + $instance = $this->getInstance( true ); + $instance->addTableCell( 'lila' )->addTableRow()->getTable(); + + // Access protected method + $reflection = new ReflectionClass( $this->getClass() ); + $method = $reflection->getMethod( 'getTableRows' ); + $method->setAccessible( true ); + + $matcher = array( + 'tag' => 'tbody', + 'descendant' => array( + 'tag' => 'tr', + 'attributes' => array( + 'class' => 'row-odd' + ), + 'child' => array( + 'tag' => 'td', + 'content' => 'lila' + ), + ) + ); + + $this->assertTag( $matcher, $method->invoke( $instance ) ); + + } + + /** + * @test TableFormatter::getTable + * + * @since 1.9 + */ + public function testStandardTable() { + + $instance = $this->getInstance(); + + // Row + cell + $instance->addTableCell( 'lala', array( 'rel' => 'tuuu' ) ) + ->addTableRow( array( 'class' => 'foo' ) ); + + $matcher = array( + 'tag' => 'table', + 'descendant' => array( + 'tag' => 'tr', + 'attributes' => array( 'class' => 'foo row-odd' ), + 'child' => array( + 'tag' => 'td', + 'content' => 'lala', + 'attributes' => array( 'rel' => 'tuuu' ) + ) + ) + ); + + $this->assertTag( $matcher, $instance->getTable() ); + + // Head + row + cell + $instance = $this->getInstance(); + $instance->addTableHeader( 'lula' ) + ->addTableCell( 'lala' ) + ->addTableRow(); + + $matcher = array( + 'tag' => 'table', + 'descendant' => array( + 'tag' => 'th', + 'child' => array( 'tag' => 'td', 'content' => 'lula' ), + ), + 'descendant' => array( + 'tag' => 'tr', + 'attributes' => array( 'class' => 'row-odd' ), + 'child' => array( 'tag' => 'td', 'content' => 'lala' ), + ) + ); + + $this->assertTag( $matcher, $instance->getTable() ); + + // HTML context + $instance = $this->getInstance( true ); + $instance->addTableHeader( 'lula' ) + ->addTableCell( 'lala' ) + ->addTableRow(); + + // Doing a lazy check here ... + $matcher = array( + 'tag' => 'table', + 'descendant' => array( + 'tag' => 'thead', + 'child' => array( 'content' => 'lula' ) + ), + 'descendant' => array( + 'tag' => 'tbody', + 'child' => array( 'content' => 'lala' ) + ), + ); + + $this->assertTag( $matcher, $instance->getTable() ); + } + + /** + * @test TableFormatter::getTable + * + * @since 1.9 + */ + public function testEmptyTable() { + $instance = $this->getInstance(); + $instance->addTableCell()->addTableRow(); + $this->assertEmpty( $instance->getTable() ); + } + + /** + * @test TableFormatter::getTable + * @test TableFormatter::transpose + * + * @since 1.9 + */ + public function testTransposedTable() { + + $instance = $this->getInstance(); + + // We need a dedicated header definition to support a table transpose + $instance->addTableHeader( 'Foo' )->addTableHeader( 'Bar' ) + ->addTableCell( 'lala', array( 'class' => 'foo' ) ) + ->addTableRow() + ->addTableCell( 'lula', array( 'rel' => 'tuuu' ) )->addTableCell( 'lila' ) + ->addTableRow(); + + $matcher = array( + 'tag' => 'tr', + 'attributes' => array( 'class' => 'row-odd' ), + 'child' => array( + 'tag' => 'th', + 'content' => 'Foo' + ), + 'descendant' => array( + 'tag' => 'td', + 'content' => 'lala', + 'attributes' => array( 'class' => 'foo' ), + ), + 'descendant' => array( + 'tag' => 'td', + 'content' => 'lula', + 'attributes' => array( 'rel' => 'tuuu' ) + ), + 'tag' => 'tr', + 'attributes' => array( 'class' => 'row-even' ), + 'child' => array( + 'tag' => 'th', + 'content' => 'Bar' + ), + 'descendant' => array( + 'tag' => 'td', + 'content' => '' + ), + 'descendant' => array( + 'tag' => 'td', + 'content' => 'lila' + ), + ); + + $this->assertTag( $matcher, $instance->transpose( true )->getTable() ); + + // HTML context + $instance = $this->getInstance( true ); + $instance->addTableHeader( 'Foo' )->addTableHeader( 'Bar' ) + ->addTableCell( 'lala', array( 'class' => 'foo' ) ) + ->addTableRow() + ->addTableCell( 'lula' )->addTableCell( 'lila' ) + ->addTableRow(); + + $matcher = array( + 'tag' => 'thead', + 'tag' => 'tbody', + 'child' => array( + 'tag' => 'tr', + 'attributes' => array( 'class' => 'row-odd' ), + 'child' => array( + 'tag' => 'th', + 'content' => 'Foo' + ), + 'descendant' => array( + 'tag' => 'td', + 'content' => 'lala', + 'attributes' => array( 'class' => 'foo' ), + ), + 'descendant' => array( + 'tag' => 'td', + 'content' => 'lula' + ), + 'tag' => 'tr', + 'attributes' => array( 'class' => 'row-even' ), + 'child' => array( + 'tag' => 'th', + 'content' => 'Bar' + ), + 'descendant' => array( + 'tag' => 'td', + 'content' => '' + ), + 'descendant' => array( + 'tag' => 'td', + 'content' => 'lila' + ), + ) + ); + + $this->assertTag( $matcher, $instance->transpose( true )->getTable() ); + + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/parserhooks/AskParserFunctionTest.php b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/AskParserFunctionTest.php new file mode 100644 index 00000000..4f2545dd --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/AskParserFunctionTest.php @@ -0,0 +1,323 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\SemanticDataValidator; + +use SMW\ExtensionContext; +use SMW\AskParserFunction; +use SMW\MessageFormatter; +use SMW\ParserData; +use SMW\QueryData; +use SMW\Settings; + +use Title; +use ParserOutput; +use ReflectionClass; + +/** + * @covers \SMW\AskParserFunction + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class AskParserFunctionTest extends ParserTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string + */ + public function getClass() { + return '\SMW\AskParserFunction'; + } + + /** + * @since 1.9 + * + * @return AskParserFunction + */ + private function newInstance( Title $title = null, ParserOutput $parserOutput = null, Settings $settings = null ) { + + if ( $title === null ) { + $title = $this->newTitle(); + } + + if ( $parserOutput === null ) { + $parserOutput = $this->newParserOutput(); + } + + if ( $settings === null ) { + $settings = $this->newSettings( array( + 'smwgQueryDurationEnabled' => false + ) ); + } + + $context = new ExtensionContext(); + $container = $context->getDependencyBuilder()->getContainer(); + + $container->registerObject( 'MessageFormatter', new MessageFormatter( $title->getPageLanguage() ) ); + $container->registerObject( 'Settings', $settings ); + + return new AskParserFunction( + $this->newParserData( $title, $parserOutput ), + $context + ); + } + + /** + * @test AskParserFunction::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @test AskParserFunction::parse + * @dataProvider queryDataProvider + * + * @since 1.9 + * + * @param array $params + * @param array $expected + */ + public function testParse( array $params, array $expected ) { + + $instance = $this->newInstance( $this->newTitle(), $this->newParserOutput() ); + $result = $instance->parse( $params ); + $this->assertInternalType( 'string', $result ); + + } + + /** + * @test AskParserFunction::parse (Test ($GLOBALS['smwgQEnabled'] = false)) + * + * @since 1.9 + */ + public function testIsQueryDisabled() { + + $title = $this->newTitle(); + $message = new MessageFormatter( $title->getPageLanguage() ); + + $instance = $this->newInstance( $title , $this->newParserOutput() ); + + $this->assertEquals( + $message->addFromKey( 'smw_iq_disabled' )->getHtml(), + $instance->isQueryDisabled(), + 'asserts a resutling disabled error message' + ); + + } + + /** + * @test AskParserFunction::setShowMode + * + * @since 1.9 + */ + public function testSetShowMode() { + + $instance = $this->newInstance(); + + $reflector = $this->newReflector(); + $showMode = $reflector->getProperty( 'showMode' ); + $showMode->setAccessible( true ); + + $this->assertFalse( + $showMode->getValue( $instance ), + 'asserts that showMode is false by default' + ); + + $instance->setShowMode( true ); + + $this->assertTrue( + $showMode->getValue( $instance ), + 'asserts that showMode is true' + ); + + } + + /** + * @test AskParserFunction::parse + * @dataProvider queryDataProvider + * + * @since 1.9 + * + * @param array $params + * @param array $expected + */ + public function testInstantiatedQueryData( array $params, array $expected, array $settings ) { + + $parserOutput = $this->newParserOutput(); + $title = $this->newTitle(); + + // Initialize and parse + $instance = $this->newInstance( $title, $parserOutput, $this->newSettings( $settings ) ); + $instance->parse( $params ); + + // Get semantic data from the ParserOutput + $parserData = $this->newParserData( $title, $parserOutput ); + + // Check the returned instance + $this->assertInstanceOf( 'SMW\SemanticData', $parserData->getData() ); + $semanticDataValidator = new SemanticDataValidator; + + // Confirm subSemanticData objects for the SemanticData instance + foreach ( $parserData->getData()->getSubSemanticData() as $containerSemanticData ){ + $this->assertInstanceOf( 'SMWContainerSemanticData', $containerSemanticData ); + $semanticDataValidator->assertThatPropertiesAreSet( $expected, $containerSemanticData ); + } + + } + + /** + * Provides sample data usually found in {{#ask}} queries + * + * @return array + */ + public function queryDataProvider() { + + $provider = array(); + + // #0 + // {{#ask: [[Modification date::+]] + // |?Modification date + // |format=list + // }} + $provider[] = array( + array( + '[[Modification date::+]]', + '?Modification date', + 'format=list' + ), + array( + 'propertyCount' => 4, + 'propertyKeys' => array( '_ASKST', '_ASKSI', '_ASKDE', '_ASKFO' ), + 'propertyValues' => array( 'list', 1, 1, '[[Modification date::+]]' ) + ), + array( + 'smwgQueryDurationEnabled' => false + ) + ); + + // #1 Query string with spaces + // {{#ask: [[Modification date::+]] [[Category:Foo bar]] [[Has title::!Foo bar]] + // |?Modification date + // |?Has title + // |format=list + // }} + $provider[] = array( + array( + '[[Modification date::+]] [[Category:Foo bar]] [[Has title::!Foo bar]]', + '?Modification date', + '?Has title', + 'format=list' + ), + array( + 'propertyCount' => 4, + 'propertyKeys' => array( '_ASKST', '_ASKSI', '_ASKDE', '_ASKFO' ), + 'propertyValues' => array( 'list', 4, 1, '[[Modification date::+]] [[Category:Foo bar]] [[Has title::!Foo bar]]' ) + ), + array( + 'smwgQueryDurationEnabled' => false + ) + ); + + // #2 + // {{#ask: [[Modification date::+]][[Category:Foo]] + // |?Modification date + // |?Has title + // |format=list + // }} + $provider[] = array( + array( + '[[Modification date::+]][[Category:Foo]]', + '?Modification date', + '?Has title', + 'format=list' + ), + array( + 'propertyCount' => 4, + 'propertyKeys' => array( '_ASKST', '_ASKSI', '_ASKDE', '_ASKFO' ), + 'propertyValues' => array( 'list', 2, 1, '[[Modification date::+]] [[Category:Foo]]' ) + ), + array( + 'smwgQueryDurationEnabled' => false + ) + ); + + // #3 Known format + // {{#ask: [[File:Fooo]] + // |?Modification date + // |default=no results + // |format=feed + // }} + $provider[] = array( + array( + '[[File:Fooo]]', + '?Modification date', + 'default=no results', + 'format=feed' + ), + array( + 'propertyCount' => 4, + 'propertyKeys' => array( '_ASKST', '_ASKSI', '_ASKDE', '_ASKFO' ), + 'propertyValues' => array( 'feed', 1, 1, '[[:File:Fooo]]' ) + ), + array( + 'smwgQueryDurationEnabled' => false + ) + ); + + // #4 Unknown format, default table + // {{#ask: [[Modification date::+]][[Category:Foo]] + // |?Modification date + // |?Has title + // |format=bar + // }} + $provider[] = array( + array( + '[[Modification date::+]][[Category:Foo]]', + '?Modification date', + '?Has title', + 'format=lula' + ), + array( + 'propertyCount' => 4, + 'propertyKeys' => array( '_ASKST', '_ASKSI', '_ASKDE', '_ASKFO' ), + 'propertyValues' => array( 'table', 2, 1, '[[Modification date::+]] [[Category:Foo]]' ) + ), + array( + 'smwgQueryDurationEnabled' => false + ) + ); + + // #5 QueryTime enabled + $provider[] = array( + array( + '[[Modification date::+]][[Category:Foo]]', + '?Modification date', + '?Has title', + 'format=lula' + ), + array( + 'propertyCount' => 5, + 'propertyKeys' => array( '_ASKST', '_ASKSI', '_ASKDE', '_ASKFO', '_ASKDU' ), + ), + array( + 'smwgQueryDurationEnabled' => true + ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/parserhooks/ConceptParserFunctionTest.php b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/ConceptParserFunctionTest.php new file mode 100644 index 00000000..7094c300 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/ConceptParserFunctionTest.php @@ -0,0 +1,211 @@ +<?php + +namespace SMW\Tests; + +use SMW\Tests\Util\ParserFactory; + +use SMW\ConceptParserFunction; +use SMW\MessageFormatter; +use SMW\ParserData; + +use Title; +use ParserOutput; + +/** + * @covers \SMW\ConceptParserFunction + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group medium + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class ConceptParserFunctionTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\ConceptParserFunction', + $this->newInstance() + ); + } + + /** + * @dataProvider namespaceDataProvider + */ + public function testErrorOnNamespace( $namespace ) { + + $title = Title::newFromText( __METHOD__, $namespace ); + + $instance = $this->newInstance( $title, new ParserOutput() ); + + $this->assertEquals( + $this->getMessageText( $title, 'smw_no_concept_namespace' ), + $instance->parse( array() ) + ); + } + + /** + * @dataProvider queryParameterProvider + */ + public function testErrorOnDoubleParse( array $params ) { + + $title = Title::newFromText( __METHOD__, SMW_NS_CONCEPT ); + + $instance = $this->newInstance( $title, new ParserOutput() ); + $instance->parse( $params ); + + $instance->parse( $params ); + + $this->assertEquals( + $this->getMessageText( $title, 'smw_multiple_concepts' ), + $instance->parse( $params ) + ); + } + + /** + * @dataProvider queryParameterProvider + */ + public function testParse( array $params, array $expected ) { + + $parserOutput = new ParserOutput(); + $title = Title::newFromText( __METHOD__, SMW_NS_CONCEPT ); + + $instance = $this->newInstance( $title, $parserOutput ); + $instance->parse( $params ); + + $parserData = new ParserData( $title, $parserOutput ); + + $this->assertCount( + $expected['propertyCount'], + $parserData->getSemanticData()->getProperties() + ); + + // Confirm concept property + foreach ( $parserData->getSemanticData()->getProperties() as $key => $diproperty ){ + $this->assertInstanceOf( 'SMWDIProperty', $diproperty ); + $this->assertEquals( '_CONC' , $diproperty->getKey() ); + + // Confirm concept property values + foreach ( $parserData->getSemanticData()->getPropertyValues( $diproperty ) as $dataItem ){ + $this->assertEquals( $expected['conceptQuery'], $dataItem->getConceptQuery() ); + $this->assertEquals( $expected['conceptDocu'], $dataItem->getDocumentation() ); + $this->assertEquals( $expected['conceptSize'], $dataItem->getSize() ); + $this->assertEquals( $expected['conceptDepth'], $dataItem->getDepth() ); + } + } + } + + public function testStaticRender() { + + $parser = ParserFactory::newFromTitle( Title::newFromText( __METHOD__ ) ); + + $this->assertInternalType( + 'string', + ConceptParserFunction::render( $parser ) + ); + } + + /** + * @return array + */ + public function queryParameterProvider() { + + $provider = array(); + + // #0 + // {{#concept: [[Modification date::+]] + // }} + $provider[] = array( + array( + '[[Modification date::+]]' + ), + array( + 'result' => true, + 'propertyCount' => 1, + 'conceptQuery' => '[[Modification date::+]]', + 'conceptDocu' => '', + 'conceptSize' => 1, + 'conceptDepth' => 1, + ) + ); + + // #1 + // {{#concept: [[Modification date::+]] + // |Foooooooo + // }} + $provider[] = array( + array( + '[[Modification date::+]]', + 'Foooooooo' + ), + array( + 'result' => true, + 'propertyCount' => 1, + 'conceptQuery' => '[[Modification date::+]]', + 'conceptDocu' => 'Foooooooo', + 'conceptSize' => 1, + 'conceptDepth' => 1, + ) + ); + + // #2 (includes Parser object) + $provider[] = array( + array( + ParserFactory::newFromTitle( Title::newFromText( __METHOD__ ) ), + '[[Modification date::+]]', + 'Foooooooo' + ), + array( + 'result' => true, + 'propertyCount' => 1, + 'conceptQuery' => '[[Modification date::+]]', + 'conceptDocu' => 'Foooooooo', + 'conceptSize' => 1, + 'conceptDepth' => 1, + ) + ); + + return $provider; + + } + + /** + * NameSpaceDataProvider + * + * @return array + */ + public function namespaceDataProvider() { + return array( + array( NS_MAIN ), + array( NS_HELP ) + ); + } + + private function newInstance( Title $title = null, ParserOutput $parserOutput = null ) { + + if ( $title === null ) { + $title = Title::newFromText( __METHOD__, SMW_NS_CONCEPT ); + } + + if ( $parserOutput === null ) { + $parserOutput = new ParserOutput(); + } + + return new ConceptParserFunction( + new ParserData( $title, $parserOutput ), + new MessageFormatter( $title->getPageLanguage() ) + ); + } + + private function getMessageText( Title $title, $error ) { + $message = new MessageFormatter( $title->getPageLanguage() ); + return $message->addFromKey( $error )->getHtml(); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/parserhooks/DeclareParserFunctionTest.php b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/DeclareParserFunctionTest.php new file mode 100644 index 00000000..c9f67949 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/DeclareParserFunctionTest.php @@ -0,0 +1,46 @@ +<?php + +namespace SMW\Test; + +use SMW\DeclareParserFunction; + +/** + * Tests for the DeclareParserFunction class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\DeclareParserFunction + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class DeclareParserFunctionTest extends ParserTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string + */ + public function getClass() { + return '\SMW\DeclareParserFunction'; + } + + /** + * @test DeclareParserFunction::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $instance = new DeclareParserFunction(); + $this->assertInstanceOf( $this->getClass(), $instance ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/parserhooks/DocumentationParserFunctionTest.php b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/DocumentationParserFunctionTest.php new file mode 100644 index 00000000..3c4844e6 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/DocumentationParserFunctionTest.php @@ -0,0 +1,57 @@ +<?php + +namespace SMW\Test; + +use SMW\DocumentationParserFunction; + +/** + * Tests for the DocumentationParserFunction class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\DocumentationParserFunction + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class DocumentationParserFunctionTest extends ParserTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string + */ + public function getClass() { + return '\SMW\DocumentationParserFunction'; + } + + /** + * @test DocumentationParserFunction::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $instance = new DocumentationParserFunction(); + $this->assertInstanceOf( $this->getClass(), $instance ); + } + + /** + * @test DocumentationParserFunction::staticInit + * + * @since 1.9 + */ + public function testStaticInit() { + $parser = $this->getParser( $this->newTitle(), $this->getUser() ); + $result = DocumentationParserFunction::staticInit( $parser ); + $this->assertTrue( $result ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/parserhooks/InfoParserFunctionTest.php b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/InfoParserFunctionTest.php new file mode 100644 index 00000000..1a704ea9 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/InfoParserFunctionTest.php @@ -0,0 +1,57 @@ +<?php + +namespace SMW\Test; + +use SMW\InfoParserFunction; + +/** + * Tests for the InfoParserFunction class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\InfoParserFunction + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class InfoParserFunctionTest extends ParserTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string + */ + public function getClass() { + return '\SMW\InfoParserFunction'; + } + + /** + * @test InfoParserFunction::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $instance = new InfoParserFunction(); + $this->assertInstanceOf( $this->getClass(), $instance ); + } + + /** + * @test InfoParserFunction::staticInit + * + * @since 1.9 + */ + public function testStaticInit() { + $parser = $this->getParser( $this->newTitle(), $this->getUser() ); + $result = InfoParserFunction::staticInit( $parser ); + $this->assertTrue( $result ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/parserhooks/ParserFunctionFactoryTest.php b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/ParserFunctionFactoryTest.php new file mode 100644 index 00000000..5f06c901 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/ParserFunctionFactoryTest.php @@ -0,0 +1,67 @@ +<?php + +namespace SMW\Test; + +use SMW\ParserFunctionFactory; + +/** + * @covers \SMW\ParserFunctionFactory + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class ParserFunctionFactoryTest extends ParserTestCase { + + /** + * @return string + */ + public function getClass() { + return '\SMW\ParserFunctionFactory'; + } + + /** + * @since 1.9 + * + * @return ParserFunctionFactory + */ + private function newInstance() { + return ParserFunctionFactory::newFromParser( $this->newParser( $this->newTitle(), $this->getUser() ) ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @dataProvider parserFunctionDataProvider + * + * @since 1.9 + */ + public function testParserFunction( $instance, $method ) { + $this->assertInstanceOf( $instance, call_user_func_array( array( $this->newInstance(), $method ), array() ) ); + } + + /** + * @return array + */ + public function parserFunctionDataProvider() { + + $provider = array(); + + $provider[] = array( '\SMW\RecurringEventsParserFunction', 'getRecurringEventsParser' ); + $provider[] = array( '\SMW\SubobjectParserFunction', 'getSubobjectParser' ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/parserhooks/RecurringEventsParserFunctionTest.php b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/RecurringEventsParserFunctionTest.php new file mode 100644 index 00000000..3a1a6f3a --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/RecurringEventsParserFunctionTest.php @@ -0,0 +1,475 @@ +<?php + +namespace SMW\Test; + +use SMW\RecurringEventsParserFunction; +use SMW\ParserParameterFormatter; +use SMW\MessageFormatter; +use SMW\Subobject; +use SMW\Settings; +use SMW\ParserData; + +use Title; +use ParserOutput; +use ReflectionClass; + +/** + * @covers \SMW\RecurringEventsParserFunction + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class RecurringEventsParserFunctionTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $subobject = new Subobject( Title::newFromText( __METHOD__ ) ); + + $settings = $this->getMockBuilder( '\SMW\Settings' ) + ->disableOriginalConstructor() + ->getMock(); + + $parserData = $this->getMockBuilder( '\SMW\ParserData' ) + ->disableOriginalConstructor() + ->getMock(); + + $messageFormatter = $this->getMockBuilder( '\SMW\MessageFormatter' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\RecurringEventsParserFunction', + new RecurringEventsParserFunction( + $parserData, + $subobject, + $messageFormatter, + $settings + ) + ); + } + + /** + * @dataProvider recurringEventsDataProvider + */ + public function testParse( array $params, array $expected ) { + + $instance = $this->acquireInstance( + Title::newFromText( __METHOD__ ), + new ParserOutput() + ); + + $result = $instance->parse( new ParserParameterFormatter( $params ) ); + + $this->assertTrue( $result !== '' ? $expected['errors'] : !$expected['errors'] ); + + $reflector = new ReflectionClass( '\SMW\RecurringEventsParserFunction' ); + $events = $reflector->getProperty( 'events' ); + $events->setAccessible( true ); + + $this->assertEquals( + $expected['parameters'], + $events->getValue( $instance )->getParameters() + ); + } + + public function testStaticRender() { + + $parser = $this->getMockBuilder( 'Parser' ) + ->disableOriginalConstructor() + ->getMock(); + + $parser->expects( $this->exactly( 2 ) ) + ->method( 'getTitle' ) + ->will( $this->returnValue( Title::newFromText( __METHOD__ ) ) ); + + $parser->expects( $this->once() ) + ->method( 'getOutput' ) + ->will( $this->returnValue( new ParserOutput ) ); + + $parser->expects( $this->once() ) + ->method( 'getTargetLanguage' ) + ->will( $this->returnValue( \Language::factory( 'en' ) ) ); + + $result = RecurringEventsParserFunction::render( $parser ); + $this->assertInternalType( 'string', $result ); + } + + /** + * @return array + */ + public function recurringEventsDataProvider() { + + $provider = array(); + + // #0 + // {{#set_recurring_event:property=Has birthday + // |start=01 Feb 1970 + // |has title= Birthday + // |unit=year + // |period=12 + // |limit=3 + // }} + $provider[] = array( + array( + 'property=Has birthday', + 'start=01 Feb 1970', + 'has title=Birthday', + 'unit=month', + 'period=12', + 'limit=3' + ), + array( + 'errors' => false, + 'dates' => array( + '1 February 1970', + '1 February 1971 00:00:00', + '1 February 1972 00:00:00', + '1 February 1973 00:00:00' + ), + 'property' => array( + 'Has birthday', + 'Has title' + ), + 'parameters' => array( + 'has title' => array( 'Birthday' ) + ) + ) + ); + + // #1 + // {{#set_recurring_event:property=Has birthday + // |start=01 Feb 1972 02:00 + // |has title=Test 12 + // |unit=week + // |period=4 + // |limit=3 + // }} + $provider[] = array( + array( + 'property=Has birthday', + 'start=01 Feb 1972 02:00', + 'has title=Test 2', + 'unit=week', + 'period=4', + 'limit=3' + ), + array( + 'errors' => false, + 'dates' => array( + '1 February 1972 02:00:00', + '29 February 1972 02:00:00', + '28 March 1972 02:00:00', + '25 April 1972 02:00:00' + ), + 'property' => array( + 'Has birthday', + 'Has title' + ), + 'parameters' => array( + 'has title' => array( 'Test 2' ) + ) + ) + ); + + // #2 + // {{#set_recurring_event:property=Has date + // |start=January 4, 2010 + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010 + // |exclude=January 18, 2010;January 25, 2010 + // }} + $provider[] = array( + array( + 'property=Has date', + 'start=January 4, 2010', + 'unit=week', + 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + 'exclude=January 18, 2010;January 25, 2010' + ), + array( + 'errors' => false, + 'dates' => array( + '4 January 2010', + '11 January 2010 00:00:00', + '1 February 2010 00:00:00', + 'March 16, 2010', + 'March 23, 2010' + ), + 'property' => 'Has date', + 'parameters' => array() + ) + ); + + + // #3 + // {{#set_recurring_event:property=Has date + // |start=January 4, 2010 + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010|+sep=; + // |exclude=January 18, 2010;January 25, 2010|+sep=; + // }} + $provider[] = array( + array( + 'property=Has date', + 'start=January 4, 2010', + 'unit=week', + 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + '+sep=;', 'exclude=January 18, 2010;January 25, 2010', + '+sep=;' + ), + array( + 'errors' => false, + 'dates' => array( + '4 January 2010', + '11 January 2010 00:00:00', + '1 February 2010 00:00:00', + 'March 16, 2010', + 'March 23, 2010' + ), + 'property' => 'Has date', + 'parameters' => array() + ) + ); + + // #4 Named page reference pointer + // {{#set_recurring_event:FooBar + // |property=Has birthday + // |start=January 4, 2010 + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010|+sep=; + // |exclude=January 18, 2010;January 25, 2010|+sep=; + // }} + $provider[] = array( + array( + 'FooBar', + 'property=Has birthday', + 'start=January 4, 2010', + 'unit=week', + 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + '+sep=;', 'exclude=January 18, 2010;January 25, 2010', + '+sep=;' + ), + array( + 'errors' => false, + 'dates' => array( + '4 January 2010', + '11 January 2010 00:00:00', + '1 February 2010 00:00:00', + 'March 16, 2010', + 'March 23, 2010' + ), + 'property' => 'Has birthday', + 'parameters' => array() + ) + ); + + // #5 Simulate first parameter starting being - raising an error + // {{#set_recurring_event:- + // property=Has date + // |start=January 4, 2010 + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010 + // |exclude=January 18, 2010;January 25, 2010 + // }} + $provider[] = array( + array( + '-', + 'property=Has date', + 'start=January 4, 2010', + 'unit=week', + 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + 'exclude=January 18, 2010;January 25, 2010' + ), + array( + 'errors' => false, + 'dates' => array(), + 'property' => '', + 'parameters' => array() + ) + ); + + // #6 Simulate first parameter starting with - raising an error + // {{#set_recurring_event:-Foo + // property=Has date + // |start=January 4, 2010 + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010 + // |exclude=January 18, 2010;January 25, 2010 + // }} + $provider[] = array( + array( + '-Foo', + 'property=Has date', + 'start=January 4, 2010', + 'unit=week', + 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + 'exclude=January 18, 2010;January 25, 2010' + ), + array( + 'errors' => true, + 'dates' => array(), + 'property' => '', + 'parameters' => array() + ) + ); + + // #7 Simulate first parameter starting with a underscore raising an error + // {{#set_recurring_event:_FooBar + // property=Has date + // |start=January 4, 2010 + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010 + // |exclude=January 18, 2010;January 25, 2010 + // }} + $provider[] = array( + array( + '_FooBar', + 'property=Has date', + 'start=January 4, 2010', + 'unit=week', + 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + 'exclude=January 18, 2010;January 25, 2010' + ), + array( + 'errors' => true, + 'dates' => array(), + 'property' => '', + 'parameters' => array() + ) + ); + + // #8 Simulate start date has wrong type + // {{#set_recurring_event:property=Has date + // |start=??? + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010 + // |exclude=January 18, 2010;January 25, 2010 + // }} + $provider[] = array( + array( + 'property=Has date', + 'start=???', + 'unit=week', + 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + 'exclude=January 18, 2010;January 25, 2010' + ), + array( + 'errors' => true, + 'dates' => array(), + 'property' => '', + 'parameters' => array() + ) + ); + + // #9 Simulate missing start date + // {{#set_recurring_event:property=Has date + // |start= + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010 + // |exclude=January 18, 2010;January 25, 2010 + // }} + $provider[] = array( + array( + 'property=Has date', + 'start=', + 'unit=week', + 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + 'exclude=January 18, 2010;January 25, 2010' + ), + array( + 'errors' => true, + 'dates' => array(), + 'property' => '', + 'parameters' => array() + ) + ); + + // #10 Simulate missing property + // {{#set_recurring_event:property= + // |start=January 4, 2010 + // |unit=week + // |period=1 + // |limit=4 + // |include=March 16, 2010;March 23, 2010|+sep=; + // |exclude=January 18, 2010;January 25, 2010|+sep=; + // }} + $provider[] = array( + array( + 'property=', + 'start=January 4, 2010', + 'unit=week', 'period=1', + 'limit=4', + 'include=March 16, 2010;March 23, 2010', + '+sep=;', + 'exclude=January 18, 2010;January 25, 2010', + '+sep=;' + ), + array( + 'errors' => true, + 'dates' => array(), + 'property' => '', + 'parameters' => array() + ) + ); + + return $provider; + } + + /** + * @return RecurringEventsParserFunction + */ + private function acquireInstance( Title $title, ParserOutput $parserOutput ) { + + $settings = array( + 'smwgDefaultNumRecurringEvents' => 100, + 'smwgMaxNumRecurringEvents' => 100 + ); + + return new RecurringEventsParserFunction( + new ParserData( $title, $parserOutput ), + new Subobject( $title ), + new MessageFormatter( \Language::factory( 'en' ) ), + Settings::newFromArray( $settings ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/parserhooks/SetParserFunctionTest.php b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/SetParserFunctionTest.php new file mode 100644 index 00000000..d9ed67d2 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/SetParserFunctionTest.php @@ -0,0 +1,176 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\SemanticDataValidator; + +use SMW\SetParserFunction; +use SMW\ParserData; +use SMW\ParserParameterFormatter; +use SMW\MessageFormatter; + +use SMWDIWikiPage; +use SMWDataItem; +use Title; +use ParserOutput; + +/** + * @covers \SMW\SetParserFunction + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +class SetParserFunctionTest extends ParserTestCase { + + public function getClass() { + return '\SMW\SetParserFunction'; + } + + /** + * @return SetParserFunction + */ + private function newInstance( Title $title = null, ParserOutput $parserOutput = null ) { + + if ( $title === null ) { + $title = $this->newTitle(); + } + + if ( $parserOutput === null ) { + $parserOutput = $this->newParserOutput(); + } + + return new SetParserFunction( + $this->newParserData( $title, $parserOutput ), + new MessageFormatter( $title->getPageLanguage() ) + ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @dataProvider getDataProvider + * + * @since 1.9 + */ + public function testParse( array $params, array $expected ) { + $instance = $this->newInstance( $this->newTitle(), $this->newParserOutput() ); + $result = $instance->parse( $this->getParserParameterFormatter( $params ) ); + + $this->assertInternalType( 'string', $result ); + } + + /** + * @dataProvider getDataProvider + * + * @since 1.9 + */ + public function testInstantiatedPropertyValues( array $params, array $expected ) { + + $parserOutput = $this->newParserOutput(); + $title = $this->newTitle(); + + // Initialize and parse + $instance = $this->newInstance( $title, $parserOutput ); + $instance->parse( $this->getParserParameterFormatter( $params ) ); + + // Re-read data from stored parserOutput + $parserData = $this->newParserData( $title, $parserOutput ); + + // Check the returned instance + $this->assertInstanceOf( '\SMW\SemanticData', $parserData->getData() ); + + $semanticDataValidator = new SemanticDataValidator; + $semanticDataValidator->assertThatPropertiesAreSet( $expected, $parserData->getSemanticData() ); + + } + + /** + * @since 1.9 + */ + public function testStaticRender() { + $parser = $this->newParser( $this->newTitle(), $this->getUser() ); + $result = SetParserFunction::render( $parser ); + $this->assertInternalType( 'string', $result ); + } + + /** + * @return array + */ + public function getDataProvider() { + return array( + + // #0 Single data set + // {{#set: + // |Foo=bar + // }} + array( + array( 'Foo=bar' ), + array( + 'errors' => 0, + 'propertyCount' => 1, + 'propertyLabels' => 'Foo', + 'propertyValues' => 'Bar' + ) + ), + + // #1 Empty data set + // {{#set: + // |Foo= + // }} + array( + array( 'Foo=' ), + array( + 'errors' => 0, + 'propertyCount' => 0, + 'propertyLabels' => '', + 'propertyValues' => '' + ) + ), + + // #2 Multiple data set + // {{#set: + // |BarFoo=9001 + // |Foo=bar + // }} + array( + array( 'Foo=bar', 'BarFoo=9001' ), + array( + 'errors' => 0, + 'propertyCount' => 2, + 'propertyLabels' => array( 'Foo', 'BarFoo' ), + 'propertyValues' => array( 'Bar', '9001' ) + ) + ), + + // #3 Multiple data set with an error record + // {{#set: + // |_Foo=9001 --> will raise an error + // |Foo=bar + // }} + array( + array( 'Foo=bar', '_Foo=9001' ), + array( + 'errors' => 1, + 'propertyCount' => 1, + 'propertyLabels' => array( 'Foo' ), + 'propertyValues' => array( 'Bar' ) + ) + ), + + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/parserhooks/ShowParserFunctionTest.php b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/ShowParserFunctionTest.php new file mode 100644 index 00000000..cea8ef7a --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/ShowParserFunctionTest.php @@ -0,0 +1,199 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\SemanticDataValidator; + +use SMW\ExtensionContext; +use SMW\ShowParserFunction; +use SMW\MessageFormatter; +use SMW\QueryData; + +use Title; +use ParserOutput; + +/** + * @covers \SMW\ShowParserFunction + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class ShowParserFunctionTest extends ParserTestCase { + + public function getClass() { + return '\SMW\ShowParserFunction'; + } + + /** + * @return ShowParserFunction + */ + private function newInstance( Title $title = null, ParserOutput $parserOutput = null ) { + + if ( $title === null ) { + $title = $this->newTitle(); + } + + if ( $parserOutput === null ) { + $parserOutput = $this->newParserOutput(); + } + + $settings = $this->newSettings( array( + 'smwgQueryDurationEnabled' => false + ) ); + + $context = new ExtensionContext(); + $container = $context->getDependencyBuilder()->getContainer(); + + $container->registerObject( 'MessageFormatter', new MessageFormatter( $title->getPageLanguage() ) ); + $container->registerObject( 'Settings', $settings ); + + return new ShowParserFunction( + $this->newParserData( $title, $parserOutput ), + $context + ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @dataProvider queryDataProvider + * + * @since 1.9 + */ + public function testParse( array $params, array $expected ) { + + $instance = $this->newInstance( $this->newTitle(), $this->newParserOutput() ); + $result = $instance->parse( $params, true ); + + if ( $expected['output'] === '' ) { + $this->assertEmpty( $result ); + } else { + $this->assertContains( $expected['output'], $result ); + } + + } + + /** + * @dataProvider queryDataProvider + * + * @since 1.9 + */ + public function testIsQueryDisabled() { + + $title = $this->newTitle(); + $message = new MessageFormatter( $title->getPageLanguage() ); + $expected = $message->addFromKey( 'smw_iq_disabled' )->getHtml(); + + $instance = $this->newInstance( $title, $this->getParserOutput() ); + + $this->assertEquals( $expected , $instance->isQueryDisabled() ); + } + + /** + * @dataProvider queryDataProvider + * + * @since 1.9 + */ + public function testInstantiatedQueryData( array $params, array $expected ) { + + $parserOutput = $this->newParserOutput(); + $title = $this->newTitle(); + + // Initialize and parse + $instance = $this->newInstance( $title, $parserOutput ); + $instance->parse( $params ); + + // Get semantic data from the ParserOutput + $parserData = $this->newParserData( $title, $parserOutput ); + + // Check the returned instance + $this->assertInstanceOf( '\SMW\SemanticData', $parserData->getData() ); + $semanticDataValidator = new SemanticDataValidator; + + // Confirm subSemanticData objects for the SemanticData instance + foreach ( $parserData->getData()->getSubSemanticData() as $containerSemanticData ){ + $this->assertInstanceOf( 'SMWContainerSemanticData', $containerSemanticData ); + $semanticDataValidator->assertThatPropertiesAreSet( $expected, $containerSemanticData ); + } + + } + + /** + * @return array + */ + public function queryDataProvider() { + + $provider = array(); + + // #0 + // {{#show: Foo + // |?Modification date + // }} + $provider[] = array( + array( + 'Foo', + '?Modification date', + ), + array( + 'output' => '', + 'propertyCount' => 4, + 'propertyKeys' => array( '_ASKFO', '_ASKDE', '_ASKSI', '_ASKST' ), + 'propertyValues' => array( 'list', 0, 1, '[[:Foo]]' ) + ) + ); + + // #1 + // {{#show: Help:Bar + // |?Modification date + // |default=no results + // }} + $provider[] = array( + array( + 'Help:Bar', + '?Modification date', + 'default=no results' + ), + array( + 'output' => 'no results', + 'propertyCount' => 4, + 'propertyKeys' => array( '_ASKFO', '_ASKDE', '_ASKSI', '_ASKST' ), + 'propertyValues' => array( 'list', 0, 1, '[[:Help:Bar]]' ) + ) + ); + + // #2 [[..]] is not acknowledged therefore displays an error message + // {{#show: [[File:Fooo]] + // |?Modification date + // |default=no results + // |format=table + // }} + $provider[] = array( + array( + '[[File:Fooo]]', + '?Modification date', + 'default=no results', + 'format=table' + ), + array( + 'output' => 'class="smwtticon warning"', // lazy content check for the error + 'propertyCount' => 4, + 'propertyKeys' => array( '_ASKFO', '_ASKDE', '_ASKSI', '_ASKST' ), + 'propertyValues' => array( 'table', 0, 1, '[[:]]' ) + ) + ); + + return $provider; + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/parserhooks/SubobjectParserFunctionTest.php b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/SubobjectParserFunctionTest.php new file mode 100644 index 00000000..7dc89081 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/parserhooks/SubobjectParserFunctionTest.php @@ -0,0 +1,397 @@ +<?php + +namespace SMW\Tests; + +use SMW\Tests\Util\SemanticDataValidator; + +use SMW\SubobjectParserFunction; +use SMW\Subobject; +use SMW\ParserParameterFormatter; +use SMW\MessageFormatter; +use SMW\ParserData; +use SMW\DIProperty; + +use SMWDataItem; +use Title; +use ParserOutput; + +/** + * @covers \SMW\SubobjectParserFunction + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SubobjectParserFunctionTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + + $subobject = new Subobject( Title::newFromText( __METHOD__ ) ); + + $parserData = $this->getMockBuilder( '\SMW\ParserData' ) + ->disableOriginalConstructor() + ->getMock(); + + $messageFormatter = $this->getMockBuilder( '\SMW\MessageFormatter' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( + '\SMW\SubobjectParserFunction', + new SubobjectParserFunction( + $parserData, + $subobject, + $messageFormatter + ) + ); + } + + /** + * @dataProvider parameterDataProvider + */ + public function testParse( array $parameters, array $expected ) { + + $subobject = new Subobject( Title::newFromText( __METHOD__ ) ); + + $instance = $this->acquireInstance( $subobject ); + $result = $instance->parse( new ParserParameterFormatter( $parameters ) ); + + $this->assertEquals( + $result !== '' , + $expected['hasErrors'] + ); + } + + /** + * @dataProvider parameterDataProvider + */ + public function testInstantiatedSubobject( array $parameters, array $expected ) { + + $subobject = new Subobject( Title::newFromText( __METHOD__ ) ); + + $instance = $this->acquireInstance( $subobject ); + $instance->parse( new ParserParameterFormatter( $parameters ) ); + + $this->assertContains( + $expected['identifier'], + $subobject->getId() + ); + } + + /** + * @dataProvider firstElementDataProvider + */ + public function testFirstElementAsProperty( $isEnabled , array $parameters, array $expected ) { + + $parserOutput = new ParserOutput(); + $title = Title::newFromText( __METHOD__ ); + $subobject = new Subobject( $title ); + + $instance = $this->acquireInstance( $subobject, $parserOutput ); + $instance->setFirstElementAsProperty( $isEnabled ); + + $instance->parse( new ParserParameterFormatter( $parameters ) ); + + // If it is enabled only check for the first character {0} that should + // contain '_' as the rest is going to be an unknown hash value + $id = $subobject->getId(); + $this->assertEquals( $expected['identifier'], $isEnabled ? $id{0} : $id ); + + $parserData = new ParserData( $title, $parserOutput ); + + // Add generated title text as property value due to the auto reference + // setting + $expected['propertyValues'][] = $title->getText(); + $semanticDataValidator = new SemanticDataValidator; + + foreach ( $parserData->getSemanticData()->getSubSemanticData() as $containerSemanticData ){ + $semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $containerSemanticData + ); + } + } + + /** + * @dataProvider parameterDataProvider + */ + public function testInstantiatedPropertyValues( array $parameters, array $expected ) { + $this->setupInstanceAndAssertSemanticData( + $parameters, + $expected + ); + } + + /** + * @dataProvider sortKeyProvider + */ + public function testSortKeyAnnotation( array $parameters, array $expected ) { + $this->setupInstanceAndAssertSemanticData( + $parameters, + $expected + ); + } + + protected function setupInstanceAndAssertSemanticData( array $parameters, array $expected ) { + + $parserOutput = new ParserOutput(); + $title = Title::newFromText( __METHOD__ ); + $subobject = new Subobject( $title ); + + $instance = $this->acquireInstance( + $subobject, + $parserOutput + ); + + $instance->parse( new ParserParameterFormatter( $parameters ) ); + + $parserData = new ParserData( + $title, + $parserOutput + ); + + $subSemanticData = $parserData->getSemanticData()->getSubSemanticData(); + + $semanticDataValidator = new SemanticDataValidator(); + + foreach ( $subSemanticData as $actualSemanticDataToAssert ){ + $semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $actualSemanticDataToAssert + ); + } + } + + public function parameterDataProvider() { + + $provider = array(); + + // Anonymous identifier + // {{#subobject: + // |Foo=bar + // }} + $provider[] = array( + array( '', 'Foo=bar' ), + array( + 'hasErrors' => false, + 'identifier' => '_', + 'propertyCount' => 1, + 'propertyLabels' => 'Foo', + 'propertyValues' => 'Bar' + ) + ); + + // Anonymous identifier + // {{#subobject:- + // |Foo=1001 9009 + // }} + $provider[] = array( + array( '-', 'Foo=1001 9009' ), + array( + 'hasErrors' => false, + 'identifier' => '_', + 'propertyCount' => 1, + 'propertyLabels' => 'Foo', + 'propertyValues' => '1001 9009' + ) + ); + + // Named identifier + // {{#subobject:FooBar + // |FooBar=Bar foo + // }} + $provider[] = array( + array( 'FooBar', 'FooBar=Bar foo' ), + array( + 'hasErrors' => false, + 'identifier' => 'FooBar', + 'propertyCount' => 1, + 'propertyLabels' => 'FooBar', + 'propertyValues' => 'Bar foo' + ) + ); + + // Named identifier + // {{#subobject:Foo bar + // |Foo=Help:Bar + // }} + $provider[] = array( + array( 'Foo bar', 'Foo=Help:Bar' ), + array( + 'hasErrors' => false, + 'identifier' => 'Foo_bar', + 'propertyCount' => 1, + 'propertyLabels' => 'Foo', + 'propertyValues' => 'Help:Bar' + ) + ); + + // Named identifier + // {{#subobject: Foo bar foo + // |Bar=foo Bar + // }} + $provider[] = array( + array( ' Foo bar foo ', 'Bar=foo Bar' ), + array( + 'hasErrors' => false, + 'identifier' => 'Foo_bar_foo', + 'propertyCount' => 1, + 'propertyLabels' => 'Bar', + 'propertyValues' => 'Foo Bar' + ) + ); + + // Named identifier + // {{#subobject: Foo bar foo + // |状況=超やばい + // |Bar=http://www.semantic-mediawiki.org/w/index.php?title=Subobject + // }} + $provider[] = array( + array( + ' Foo bar foo ', + '状況=超やばい', + 'Bar=http://www.semantic-mediawiki.org/w/index.php?title=Subobject' ), + array( + 'hasErrors' => false, + 'identifier' => 'Foo_bar_foo', + 'propertyCount' => 2, + 'propertyLabels' => array( '状況', 'Bar' ), + 'propertyValues' => array( '超やばい', 'Http://www.semantic-mediawiki.org/w/index.php?title=Subobject' ) + ) + ); + + // Returns an error due to wrong declaration (see Modification date) + // Get the right language for an error object + $diPropertyError = new DIProperty( DIProperty::TYPE_ERROR ); + + // {{#subobject: Foo bar foo + // |Bar=foo Bar + // |Modification date=foo Bar + // }} + $provider[] = array( + array( ' Foo bar foo ', 'Bar=foo Bar', 'Modification date=foo Bar' ), + array( + 'hasErrors' => true, + 'identifier' => 'Foo_bar_foo', + 'propertyCount' => 2, + 'propertyLabels' => array( 'Bar', $diPropertyError->getLabel() ), + 'propertyValues' => array( 'Foo Bar', 'Modification date' ) + ) + ); + + return $provider; + } + + public function firstElementDataProvider() { + + $provider = array(); + + // #0 / asserting that a named identifier was turned into an anonymous id + // {{#subobject: Foo bar foo + // |Bar=foo Bar + // }} + $provider[] = array( + true, + array( ' Foo bar foo ', 'Bar=foo Bar' ), + array( + 'hasErrors' => false, + 'identifier' => '_', + 'propertyCount' => 2, + 'propertyLabels' => array( 'Bar', 'Foo bar foo' ), + 'propertyValues' => array( 'Foo Bar' ) // additional value is added during runtime + ) + ); + + // #1 / asserting the validity of the named identifier + // {{#subobject: Foo bar foo + // |Bar=foo Bar + // }} + $provider[] = array( + false, + array( ' Foo bar foo ', 'Bar=foo Bar' ), + array( + 'hasErrors' => false, + 'identifier' => 'Foo_bar_foo', + 'propertyCount' => 1, + 'propertyLabels' => array( 'Bar' ), + 'propertyValues' => array( 'Foo Bar' ) + ) + ); + + return $provider; + } + + public function sortKeyProvider() { + + $provider = array(); + + // #0 @sortkey + // {{#subobject: + // |Bar=foo Bar + // |@sortkey=9999 + // }} + $provider[] = array( + array( + 'Bar=foo Bar', + '@sortkey=9999' + ), + array( + 'propertyCount' => 2, + 'properties' => array( + new DIProperty( 'Bar' ), + new DIProperty( '_SKEY' ) + ), + 'propertyValues' => array( + 'Foo Bar', + '9999' + ) + ) + ); + + // #1 @sortkey being empty + // {{#subobject: + // |Bar=foo Bar + // |@sortkey= + // }} + $provider[] = array( + array( + 'Bar=foo Bar', + '@sortkey=' + ), + array( + 'propertyCount' => 1, + 'properties' => array( + new DIProperty( 'Bar' ) + ), + 'propertyValues' => array( + 'Foo Bar' + ) + ) + ); + + return $provider; + } + + /** + * @return SubobjectParserFunction + */ + private function acquireInstance( Subobject $subobject, ParserOutput $parserOutput = null ) { + + if ( $parserOutput === null ) { + $parserOutput = new ParserOutput(); + } + + return new SubobjectParserFunction( + new ParserData( $subobject->getTitle(), $parserOutput ), + $subobject, + new MessageFormatter( $subobject->getTitle()->getPageLanguage() ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/query/QueryDescriptionTest.php b/SemanticMediaWiki/tests/phpunit/includes/query/QueryDescriptionTest.php new file mode 100644 index 00000000..1eab544f --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/query/QueryDescriptionTest.php @@ -0,0 +1,270 @@ +<?php + +namespace SMW\Test; + +/** + * Tests for the QueryData class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMWDescription + * @covers \SMWThingDescription + * @covers \SMWClassDescription + * @covers \SMWConceptDescription + * @covers \SMWNamespaceDescription + * @covers \SMWValueDescription + * @covers \SMWConjunction + * @covers \SMWDisjunction + * @covers \SMWSomeProperty + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class QueryDescriptionTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return false; + } + + /** + * @dataProvider descriptionDataProvider + * + * @param $setup + * @param $expectedSet + */ + public function testGenericInterface( $setup, $expectedSet ) { + + $this->assertInstanceOf( $setup['class'] ,$setup['description'] ); + + foreach ( $expectedSet as $method => $value ) { + + $caller = array( $setup['description'], $method ); + $parameters = array(); + $expected = $value; + + // pass-by-reference + if ( $method === 'prune' ) { + $maxsize = $value['parameters'][0]; + $maxDepth = $value['parameters'][1]; + $log = $value['parameters'][2]; + + $parameters = array( &$maxsize, &$maxDepth, &$log ); + $expected = $value['result']; + } + + $result = call_user_func_array( $caller, $parameters ); + + $this->assertEquals( + $expected, + $result, + "Asserts that {$method} returns a result" + ); + + } + + } + + /** + * @return array + */ + public function descriptionDataProvider() { + + $provider = array(); + + // #0 SMWThingDescription + $description = new \SMWThingDescription(); + + $provider[] = array( + array( + 'description' => $description, + 'class' => 'SMWThingDescription', + ), + array( + 'getQueryString' => '', + 'isSingleton' => false, + 'getPrintRequests' => array(), + 'getSize' => 0, + 'getDepth' => 0, + 'getQueryFeatures' => 0, + 'prune' => array( 'parameters' => array( 1, 1, 1 ), 'result' => $description ) + ) + ); + + // #1 SMWClassDescription + $content = $this->newMockBuilder()->newObject( 'DIWikiPage', array( + 'getDBkey' => 'Lula' + ) ); + + $description = new \SMWClassDescription( $content ); + + $provider[] = array( + array( + 'description' => $description, + 'class' => 'SMWClassDescription', + ), + array( + 'getQueryString' => '[[::Lula]]', + 'isSingleton' => false, + 'getPrintRequests' => array(), + 'getSize' => 1, + 'getDepth' => 0, + 'getCategories' => array( $content ), + 'getQueryFeatures' => 2, + 'prune' => array( 'parameters' => array( 1, 1, 1 ), 'result' => $description ) + ) + ); + + // #2 SMWConceptDescription + $content = $this->newMockBuilder()->newObject( 'DIWikiPage', array( + 'getDBkey' => 'Lila' + ) ); + + $description = new \SMWConceptDescription( $content ); + + $provider[] = array( + array( + 'description' => $description, + 'class' => 'SMWConceptDescription', + ), + array( + 'getQueryString' => '[[::Lila]]', + 'getConcept' => $content, + 'isSingleton' => false, + 'getPrintRequests' => array(), + 'getSize' => 1, + 'getDepth' => 0, + 'getQueryFeatures' => 4, + 'prune' => array( 'parameters' => array( 1, 1, 1 ), 'result' => $description ) + ) + ); + + // #3 SMWNamespaceDescription + $description = new \SMWNamespaceDescription( NS_MAIN ); + + $provider[] = array( + array( + 'description' => $description, + 'class' => 'SMWNamespaceDescription', + ), + array( + 'getQueryString' => "[[:+]]", + 'getNamespace' => NS_MAIN, + 'isSingleton' => false, + 'getPrintRequests' => array(), + 'getSize' => 1, + 'getDepth' => 0, + 'getQueryFeatures' => 8, + 'prune' => array( 'parameters' => array( 1, 1, 1 ), 'result' => $description ) + ) + ); + + // #4 SMWValueDescription + $dataItem = $this->newMockBuilder()->newObject( 'DIWikiPage', array( + 'getDBkey' => 'Lamba', + ) ); + + $description = new \SMWValueDescription( $dataItem, null, SMW_CMP_EQ ); + + $provider[] = array( + array( + 'description' => $description, + 'class' => 'SMWValueDescription', + ), + array( + 'getQueryString' => "[[:::Lamba]]", + 'isSingleton' => true, + 'getDataItem' => $dataItem, + 'getComparator' => SMW_CMP_EQ, + 'getPrintRequests' => array(), + 'getSize' => 1, + 'getDepth' => 0, + 'getQueryFeatures' => 0, + 'prune' => array( 'parameters' => array( 1, 1, 1 ), 'result' => $description ) + ) + ); + + // #5 SMWConjunction + $nsDescription = new \SMWNamespaceDescription( NS_MAIN ); + $description = new \SMWConjunction( array( new \SMWThingDescription(), $nsDescription ) ); + + $provider[] = array( + array( + 'description' => $description, + 'class' => 'SMWConjunction', + ), + array( + 'getQueryString' => '[[:+]]', + 'isSingleton' => false, + 'getPrintRequests' => array(), + 'getSize' => 1, + 'getDepth' => 0, + 'getQueryFeatures' => 24, + 'prune' => array( 'parameters' => array( 1, 1, array() ), 'result' => $nsDescription ) + ) + ); + + // #6 SMWDisjunction + $nsDescription = new \SMWNamespaceDescription( NS_MAIN ); + $thingDescription = new \SMWThingDescription(); + $description = new \SMWDisjunction( array( $thingDescription, $nsDescription ) ); + + $provider[] = array( + array( + 'description' => $description, + 'class' => 'SMWDisjunction', + ), + array( + 'getQueryString' => '+', + 'isSingleton' => false, + 'getPrintRequests' => array(), + 'getSize' => 0, + 'getDepth' => 0, + 'getQueryFeatures' => 32, + 'prune' => array( 'parameters' => array( 1, 1, array() ), 'result' => $thingDescription ) + ) + ); + + // #7 SMWSomeProperty + $thingDescription = new \SMWThingDescription(); + + $property = $this->newMockBuilder()->newObject( 'DIProperty', array( + 'getDBkey' => 'Property', + ) ); + + $description = new \SMWSomeProperty( $property, $thingDescription ); + + $provider[] = array( + array( + 'description' => $description, + 'class' => 'SMWSomeProperty', + ), + array( + 'getQueryString' => '[[::+]]', + 'isSingleton' => false, + 'getPrintRequests' => array(), + 'getSize' => 1, + 'getDepth' => 1, + 'getQueryFeatures' => 1, + 'prune' => array( 'parameters' => array( 1, 1, array() ), 'result' => $description ) + ) + ); + + return $provider; + } + + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/query/QueryParserTest.php b/SemanticMediaWiki/tests/phpunit/includes/query/QueryParserTest.php new file mode 100644 index 00000000..12f1c6c6 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/query/QueryParserTest.php @@ -0,0 +1,308 @@ +<?php + +namespace SMW\Tests\Query; + +use SMW\DIWikiPage; +use SMW\DIProperty; + +use SMWQueryParser as QueryParser; +use SMWDIBlob as DIBlob; +use SMWDINumber as DINumber; +use SMWQuery as Query; +use SMWSomeProperty as SomeProperty; +use SMWThingDescription as ThingDescription; +use SMWValueDescription as ValueDescription; +use SMWConjunction as Conjunction; +use SMWDisjunction as Disjunction; +use SMWClassDescription as ClassDescription; +use SMWNamespaceDescription as NamespaceDescription; + +/** + * @covers \SMWQueryParser + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class QueryParserTest extends \PHPUnit_Framework_TestCase { + + private $queryParser; + + protected function setUp() { + parent::setUp(); + + $this->queryParser = new QueryParser(); + } + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMWQueryParser', + new QueryParser() + ); + } + + public function testPropertyWildardDescription() { + + $description = new SomeProperty( + DIProperty::newFromUserLabel( 'Foo' )->setPropertyTypeId( '_wpg' ), + new ThingDescription() + ); + + $this->assertEquals( + $description, + $this->queryParser->getQueryDescription( '[[Foo::+]]' ) + ); + } + + public function testNamespaceWildardDescription() { + + $description = new NamespaceDescription( NS_MAIN ); + + $this->assertEquals( + $description, + $this->queryParser->getQueryDescription( '[[:+]]' ) + ); + } + + public function testPageDescription() { + + $description = new ValueDescription( new DIWikiPage( 'Foo', NS_MAIN, '' ) ); + + $this->assertEquals( + $description, + $this->queryParser->getQueryDescription( '[[Foo]]' ) + ); + } + + public function testPropertyNotEqualValueDescription() { + + $description = new SomeProperty( + DIProperty::newFromUserLabel( 'Has foo' )->setPropertyTypeId( '_wpg' ), + new ValueDescription( + 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 = new SomeProperty( + DIProperty::newFromUserLabel( 'Has foo', true )->setPropertyTypeId( '_wpg' ), + new ValueDescription( + 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 = new SomeProperty( + DIProperty::newFromUserLabel( 'One' )->setPropertyTypeId( '_wpg' ), + new ValueDescription( + new DIWikiPage( 'A', NS_MAIN, '' ), + DIProperty::newFromUserLabel( 'One' )->setPropertyTypeId( '_wpg' ), SMW_CMP_GEQ ) + ); + + $someLessThanOrEqualProperty = new SomeProperty( + DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ), + new ValueDescription( + new DIWikiPage( 'D', NS_MAIN, '' ), + DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ), SMW_CMP_LEQ ) + ); + + $classDescription = new ClassDescription( + new DIWikiPage( 'Foo', NS_CATEGORY, '' ) + ); + + $description = new Conjunction(); + $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 = new SomeProperty( + DIProperty::newFromUserLabel( 'One' )->setPropertyTypeId( '_wpg' ), + new SomeProperty( + DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ), + new ValueDescription( + new DIWikiPage( 'Bar', NS_MAIN, '' ), + DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ), SMW_CMP_EQ + ) + ) + ); + + $classDescription = new ClassDescription( + new DIWikiPage( 'Foo', NS_CATEGORY, '' ) + ); + + $description = new Conjunction(); + $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 = new SomeProperty( + DIProperty::newFromUserLabel( 'One' )->setPropertyTypeId( '_wpg' ), + new SomeProperty( + DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ), + new ValueDescription( + new DIWikiPage( 'Bar', NS_MAIN, '' ), + DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ), SMW_CMP_EQ + ) + ) + ); + + $classDescription = new ClassDescription( + new DIWikiPage( 'Foo', NS_CATEGORY, '' ) + ); + + $description = new Disjunction(); + $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 = new ClassDescription( + new DIWikiPage( 'Foo', NS_CATEGORY, '' ) + ); + + $classBarDescription = new ClassDescription( + new DIWikiPage( 'Bar', NS_CATEGORY, '' ) + ); + + $description = new Disjunction(); + $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 = new SomeProperty( + DIProperty::newFromUserLabel( 'One' )->setPropertyTypeId( '_wpg' ), + new SomeProperty( + DIProperty::newFromUserLabel( '_SOBJ' )->setPropertyTypeId( '__sob' ), + new SomeProperty( + DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ), + new ValueDescription( + 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 = new Disjunction( array( + new ValueDescription( new DIWikiPage( 'Foo', NS_MAIN ), $property ), + new ValueDescription( new DIWikiPage( 'Bar', NS_MAIN ), $property ) + ) ); + + $description = new SomeProperty( + $property, + $disjunction + ); + + $this->assertEquals( + $description, + $this->queryParser->getQueryDescription( '[[HasSomeProperty::Foo||Bar]]' ) + ); + } + + public function testNestedPropertyConjunction() { + + $property = DIProperty::newFromUserLabel( 'Born in' ); + $property->setPropertyTypeId( '_wpg' ); + + $conjunction = new Conjunction( array( + new ClassDescription( new DIWikiPage( 'City', NS_CATEGORY ) ), + new SomeProperty( + DIProperty::newFromUserLabel( 'Located in' )->setPropertyTypeId( '_wpg' ), + new ValueDescription( + new DIWikiPage( 'Outback', NS_MAIN ), + DIProperty::newFromUserLabel( 'Located in' )->setPropertyTypeId( '_wpg' ) ) + ) + ) + ); + + $description = new SomeProperty( + $property, + $conjunction + ); + + $this->assertEquals( + $description, + $this->queryParser->getQueryDescription( '[[born in::<q>[[Category:City]] [[located in::Outback]]</q>]]' ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/query/QueryProcessorTest.php b/SemanticMediaWiki/tests/phpunit/includes/query/QueryProcessorTest.php new file mode 100644 index 00000000..a8d6f806 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/query/QueryProcessorTest.php @@ -0,0 +1,62 @@ +<?php +/** + * @file + * @since 1.8 + * @ingroup SMW + * @ingroup Test + */ + +namespace SMW\Test; + +use SMW\Tests\MwDBaseUnitTestCase; +use SMWQueryProcessor; + +/** + * Tests for the SMWQueryProcessor class. + * + * @since 1.8 + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group SMWQueries + * @group SMWQueryProcessorTest + * + * @author Nischay Nahata + */ +class SMWQueryProcessorTest extends MwDBaseUnitTestCase { + + public function createQueryDataProvider() { + return array( + array( '[[Modification date::+]]|?Modification date|sort=Modification date|order=desc' ), + ); + } + + /** + * @dataProvider createQueryDataProvider + */ + public function testCreateQuery( $query ) { + // TODO: this prevents doing [[Category:Foo||bar||baz]], must document. + $rawParams = explode( '|', $query ); + + list( $queryString, $parameters, $printouts ) = SMWQueryProcessor::getComponentsFromFunctionParams( $rawParams, false ); + + SMWQueryProcessor::addThisPrintout( $printouts, $parameters ); + + $parameters = SMWQueryProcessor::getProcessedParams( $parameters, $printouts ); + + $this->assertInstanceOf( + '\SMWQuery', + SMWQueryProcessor::createQuery( + $queryString, + $parameters, + SMWQueryProcessor::SPECIAL_PAGE, + '', + $printouts + ), + "Result should be instance of SMWQuery." + ); + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/query/QueryTest.php b/SemanticMediaWiki/tests/phpunit/includes/query/QueryTest.php new file mode 100644 index 00000000..c4e7c6b3 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/query/QueryTest.php @@ -0,0 +1,93 @@ +<?php + +namespace SMW\Tests; + +use SMWQuery as Query; + +/** + * @covers \SMWQuery + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class QueryTest extends \PHPUnit_Framework_TestCase { + + private $smwgQMaxLimit; + private $smwgQMaxInlineLimit; + + protected function setUp() { + parent::setUp(); + + $this->smwgQMaxLimit = $GLOBALS['smwgQMaxLimit']; + $this->smwgQMaxInlineLimit = $GLOBALS['smwgQMaxInlineLimit']; + } + + public function testCanConstruct() { + + $description = $this->getMockForAbstractClass( '\SMWDescription' ); + + $this->assertInstanceOf( + '\SMWQuery', + new Query( $description ) + ); + } + + public function testSetGetLimitForLowerbound() { + + $description = $this->getMockForAbstractClass( '\SMWDescription' ); + + $instance = new Query( $description, true, false ); + + $lowerboundLimit = 1; + + $this->assertGreaterThan( $lowerboundLimit, $this->smwgQMaxLimit ); + $this->assertGreaterThan( $lowerboundLimit, $this->smwgQMaxInlineLimit ); + + $instance->setLimit( $lowerboundLimit, true ); + $this->assertEquals( $lowerboundLimit, $instance->getLimit() ); + + $instance->setLimit( $lowerboundLimit, false ); + $this->assertEquals( $lowerboundLimit, $instance->getLimit() ); + } + + public function testSetGetLimitForUpperboundWhereLimitIsRestrictedByGLOBALRequirements() { + + $description = $this->getMockForAbstractClass( '\SMWDescription' ); + + $instance = new Query( $description, true, false ); + + $upperboundLimit = 999999999; + + $this->assertLessThan( $upperboundLimit, $this->smwgQMaxLimit ); + $this->assertLessThan( $upperboundLimit, $this->smwgQMaxInlineLimit ); + + $instance->setLimit( $upperboundLimit, true ); + $this->assertEquals( $this->smwgQMaxInlineLimit, $instance->getLimit() ); + + $instance->setLimit( $upperboundLimit, false ); + $this->assertEquals( $this->smwgQMaxLimit, $instance->getLimit() ); + } + + public function testSetGetLimitForUpperboundWhereLimitIsUnrestricted() { + + $description = $this->getMockForAbstractClass( '\SMWDescription' ); + + $instance = new Query( $description, true, false ); + + $upperboundLimit = 999999999; + + $this->assertLessThan( $upperboundLimit, $this->smwgQMaxLimit ); + $this->assertLessThan( $upperboundLimit, $this->smwgQMaxInlineLimit ); + + $instance->setUnboundLimit( $upperboundLimit ); + $this->assertEquals( $upperboundLimit, $instance->getLimit() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/query/profiler/DescriptionProfileTest.php b/SemanticMediaWiki/tests/phpunit/includes/query/profiler/DescriptionProfileTest.php new file mode 100644 index 00000000..291bcabe --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/query/profiler/DescriptionProfileTest.php @@ -0,0 +1,89 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\SemanticDataValidator; +use SMW\Tests\Util\Mock\MockObjectBuilder; +use SMW\Tests\Util\Mock\CoreMockObjectRepository; + +use SMW\Query\Profiler\DescriptionProfile; +use SMW\Query\Profiler\NullProfile; +use SMW\HashIdGenerator; +use SMW\Subobject; + +use Title; + +/** + * @covers \SMW\Query\Profiler\DescriptionProfile + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class DescriptionProfileTest extends \PHPUnit_Framework_TestCase { + + public function getClass() { + return '\SMW\Query\Profiler\DescriptionProfile'; + } + + /** + * @return DescriptionProfile + */ + private function newInstance( $description = null ) { + + if ( $description === null ) { + $mockBuilder = new MockObjectBuilder( new CoreMockObjectRepository() ); + $description = $mockBuilder->newObject( 'QueryDescription' ); + } + + $profiler = new NullProfile( + new Subobject( Title::newFromText( __METHOD__ ) ), + new HashIdGenerator( 'Foo' ) + ); + + return new DescriptionProfile( $profiler, $description ); + } + + /** + * @since 1.9 + */ + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testCreateProfile() { + + $mockBuilder = new MockObjectBuilder( new CoreMockObjectRepository() ); + $description = $mockBuilder->newObject( 'QueryDescription', array( + 'getQueryString' => 'Foo', + 'getSize' => 55, + 'getDepth' => 9001 + ) ); + + $instance = $this->newInstance( $description ); + $instance->addAnnotation(); + + $expected = array( + 'propertyCount' => 3, + 'propertyKeys' => array( '_ASKST', '_ASKSI', '_ASKDE' ), + 'propertyValues' => array( 'Foo', 55, 9001 ) + ); + + $semanticDataValidator = new SemanticDataValidator; + $semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance->getContainer()->getSemanticData() + ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/query/profiler/DurationProfileTest.php b/SemanticMediaWiki/tests/phpunit/includes/query/profiler/DurationProfileTest.php new file mode 100644 index 00000000..64d16548 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/query/profiler/DurationProfileTest.php @@ -0,0 +1,91 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\SemanticDataValidator; + +use SMW\Query\Profiler\DurationProfile; +use SMW\Query\Profiler\NullProfile; +use SMW\HashIdGenerator; +use SMW\Subobject; + +use Title; + +/** + * @covers \SMW\Query\Profiler\DurationProfile + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class DurationProfileTest extends \PHPUnit_Framework_TestCase { + + public function getClass() { + return '\SMW\Query\Profiler\DurationProfile'; + } + + /** + * @return DurationProfile + */ + private function newInstance( $duration = 0 ) { + + $profiler = new NullProfile( + new Subobject( Title::newFromText( __METHOD__ ) ), + new HashIdGenerator( 'Foo' ) + ); + + return new DurationProfile( $profiler, $duration ); + } + + /** + * @since 1.9 + */ + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @dataProvider durationDataProvider + * + * @since 1.9 + */ + public function testCreateProfile( $duration, $expected ) { + + $instance = $this->newInstance( $duration ); + $instance->addAnnotation(); + + $semanticDataValidator = new SemanticDataValidator; + $semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance->getContainer()->getSemanticData() + ); + + } + + /** + * @since 1.9 + */ + public function durationDataProvider() { + + $provider = array(); + + $provider[] = array( 0, array( + 'propertyCount' => 0 + ) ); + + $provider[] = array( 0.9001, array( + 'propertyCount' => 1, + 'propertyKeys' => array( '_ASKDU' ), + 'propertyValues' => array( 0.9001 ) + ) ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/query/profiler/FormatProfileTest.php b/SemanticMediaWiki/tests/phpunit/includes/query/profiler/FormatProfileTest.php new file mode 100644 index 00000000..f2023458 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/query/profiler/FormatProfileTest.php @@ -0,0 +1,75 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\SemanticDataValidator; + +use SMW\Query\Profiler\FormatProfile; +use SMW\Query\Profiler\NullProfile; +use SMW\HashIdGenerator; +use SMW\Subobject; + +use Title; + +/** + * @covers \SMW\Query\Profiler\FormatProfile + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class FormatProfileTest extends \PHPUnit_Framework_TestCase { + + public function getClass() { + return '\SMW\Query\Profiler\FormatProfile'; + } + + /** + * @return FormatProfile + */ + private function newInstance( $format = 'Foo' ) { + + $profiler = new NullProfile( + new Subobject( Title::newFromText( __METHOD__ ) ), + new HashIdGenerator( 'Foo' ) + ); + + return new FormatProfile( $profiler, $format ); + } + + /** + * @since 1.9 + */ + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testCreateProfile() { + + $instance = $this->newInstance( 'Foo' ); + $instance->addAnnotation(); + + $expected = array( + 'propertyCount' => 1, + 'propertyKeys' => array( '_ASKFO' ), + 'propertyValues' => array( 'Foo' ) + ); + + $semanticDataValidator = new SemanticDataValidator; + $semanticDataValidator->assertThatPropertiesAreSet( + $expected, + $instance->getContainer()->getSemanticData() + ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/query/profiler/NullProfileTest.php b/SemanticMediaWiki/tests/phpunit/includes/query/profiler/NullProfileTest.php new file mode 100644 index 00000000..d9839191 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/query/profiler/NullProfileTest.php @@ -0,0 +1,65 @@ +<?php + +namespace SMW\Test; + +use SMW\HashIdGenerator; +use SMW\Query\Profiler\NullProfile; +use SMW\Subobject; + +/** + * @covers \SMW\Query\Profiler\NullProfile + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class NullProfileTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\Query\Profiler\NullProfile'; + } + + /** + * @since 1.9 + * + * @return NullProfile + */ + private function newInstance() { + return new NullProfile( + new Subobject( $this->newTitle() ), + new HashIdGenerator( 'Foo' ) + ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testAvailableMethods() { + + $instance = $this->newInstance(); + $instance->addAnnotation(); + + $this->assertInstanceOf( '\SMW\DIProperty', $instance->getProperty() ); + $this->assertInstanceOf( '\SMWDIContainer', $instance->getContainer() ); + $this->assertInstanceOf( '\SMWContainerSemanticData', $instance->getSemanticData() ); + $this->assertEmpty( $instance->getErrors() ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/querypages/PropertiesQueryPageTest.php b/SemanticMediaWiki/tests/phpunit/includes/querypages/PropertiesQueryPageTest.php new file mode 100644 index 00000000..c0e8be4f --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/querypages/PropertiesQueryPageTest.php @@ -0,0 +1,324 @@ +<?php + +namespace SMW\Test; + +use SMW\PropertiesQueryPage; +use SMW\MessageFormatter; +use SMW\ArrayAccessor; + +use SMWDataItem; + +/** + * @covers \SMW\PropertiesQueryPage + * @covers \SMW\QueryPage + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group medium + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class PropertiesQueryPageTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\PropertiesQueryPage'; + } + + /** + * @since 1.9 + * + * @return DIWikiPage + */ + private function getMockDIWikiPage( $exists = true ) { + + $text = $this->newRandomString(); + + $title = $this->newMockBuilder()->newObject( 'Title', array( + 'exists' => $exists, + 'getText' => $text, + 'getNamespace' => NS_MAIN, + 'getPrefixedText' => $text + ) ); + + $diWikiPage = $this->newMockBuilder()->newObject( 'DIWikiPage', array( + 'getTitle' => $title, + ) ); + + return $diWikiPage; + } + + /** + * @since 1.9 + * + * @return PropertiesQueryPage + */ + private function newInstance( $result = null, $values = array(), $settings = array() ) { + + $collector = $this->newMockBuilder()->newObject( 'CacheableResultCollector', array( + 'getResults' => $result + ) ); + + $mockStore = $this->newMockBuilder()->newObject( 'Store', array( + 'getPropertyValues' => $values, + 'getPropertiesSpecial' => $collector + ) ); + + if ( $settings === array() ) { + $settings = array( + 'smwgPDefaultType' => '_wpg', + 'smwgPropertyLowUsageThreshold' => 5, + 'smwgPropertyZeroCountDisplay' => true + ); + } + + $instance = new PropertiesQueryPage( $mockStore, $this->newSettings( $settings ) ); + $instance->setContext( $this->newContext() ); + + return $instance; + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testFormatResultDIError() { + + $skin = $this->getMock( 'Skin' ); + + $instance = $this->newInstance(); + $error = $this->newRandomString(); + $diError = $this->newMockBuilder()->newObject( 'DIError', array( + 'getErrors' => $error + ) ); + + $result = $instance->formatResult( + $skin, + array( $diError, null ) + ); + + $this->assertInternalType( 'string', $result ); + $this->assertContains( $error, $result ); + + } + + /** + * @since 1.9 + */ + public function testInvalidResultException() { + + $this->setExpectedException( '\SMW\InvalidResultException' ); + + $instance = $this->newInstance(); + $skin = $this->getMock( 'Skin' ); + + $this->assertInternalType( 'string', $instance->formatResult( $skin, null ) ); + + } + + /** + * @dataProvider getUserDefinedDataProvider + * + * @note Title, wikiPage, and property label are randomized therefore + * the expected comparison value is determined after the property object + * has been mocked + * + * @since 1.9 + */ + public function testFormatPropertyItemUserDefined( $isUserDefined ) { + + $skin = $this->getMock( 'Skin' ); + + // Title exists + $count = rand(); + $instance = $this->newInstance(); + $property = $this->newMockBuilder()->newObject( 'DIProperty', array( + 'isUserDefined' => $isUserDefined, + 'getDiWikiPage' => $this->getMockDIWikiPage( true ), + 'getLabel' => $this->newRandomString(), + ) ); + + $expected = $property->getDiWikiPage()->getTitle()->getText(); + $result = $instance->formatResult( $skin, array( $property, $count ) ); + + $this->assertInternalType( 'string', $result ); + $this->assertContains( $expected, $result ); + + // Title does not exists + $count = rand(); + $instance = $this->newInstance(); + + $property = $this->newMockBuilder()->newObject( 'DIProperty', array( + 'isUserDefined' => $isUserDefined, + 'getDiWikiPage' => $this->getMockDIWikiPage( false ), + 'getLabel' => $this->newRandomString(), + ) ); + + $expected = $property->getDiWikiPage()->getTitle()->getText(); + $result = $instance->formatResult( $skin, array( $property, $count ) ); + + $this->assertInternalType( 'string', $result ); + $this->assertContains( $expected, $result ); + + // Multiple entries + $count = rand(); + $multiple = array( $this->getMockDIWikiPage(), $this->getMockDIWikiPage() ); + + $property = $this->newMockBuilder()->newObject( 'DIProperty', array( + 'isUserDefined' => $isUserDefined, + 'getDiWikiPage' => $this->getMockDIWikiPage( true ), + 'getLabel' => $this->newRandomString(), + ) ); + + $expected = $property->getDiWikiPage()->getTitle()->getText(); + $instance = $this->newInstance( null, $multiple ); + + $result = $instance->formatResult( $skin, array( $property, $count ) ); + + $this->assertInternalType( 'string', $result ); + $this->assertContains( $expected, $result ); + + } + + /** + * @since 1.9 + */ + public function testFormatPropertyItemZeroDisplay() { + + $skin = $this->getMock( 'Skin' ); + + $count = 0; + $instance = $this->newInstance( null, array(), array( + 'smwgPropertyZeroCountDisplay' => false + ) ); + + $property = $this->newMockBuilder()->newObject( 'DIProperty', array( + 'isUserDefined' => true, + 'getDiWikiPage' => $this->getMockDIWikiPage( true ), + 'getLabel' => $this->newRandomString(), + ) ); + + $result = $instance->formatResult( $skin, array( $property, $count ) ); + + $this->assertInternalType( 'string', $result ); + $this->assertEmpty( $result ); + } + + /** + * @since 1.9 + */ + public function testFormatPropertyItemTitleNull() { + + $skin = $this->getMock( 'Skin' ); + + $count = rand(); + $instance = $this->newInstance(); + + $property = $this->newMockBuilder()->newObject( 'DIProperty', array( + 'isUserDefined' => true, + 'getLabel' => $this->newRandomString(), + ) ); + + $expected = $property->getLabel(); + $result = $instance->formatResult( $skin, array( $property, $count ) ); + + $this->assertInternalType( 'string', $result ); + $this->assertContains( $expected, $result ); + } + + /** + * @since 1.9 + */ + public function testFormatPropertyItemLowUsageThreshold() { + + $skin = $this->getMock( 'Skin' ); + + $count = rand(); + $instance = $this->newInstance( null, array(), array( + 'smwgPropertyLowUsageThreshold' => $count + 1, + 'smwgPDefaultType' => '_wpg' + ) ); + + $property = $this->newMockBuilder()->newObject( 'DIProperty', array( + 'isUserDefined' => true, + 'getDiWikiPage' => $this->getMockDIWikiPage( true ), + 'getLabel' => $this->newRandomString(), + ) ); + + $expected = $property->getLabel(); + $result = $instance->formatResult( $skin, array( $property, $count ) ); + + $this->assertInternalType( 'string', $result ); + $this->assertContains( $expected, $result ); + } + + /** + * @return array + */ + public function getUserDefinedDataProvider() { + return array( array( true ), array( false ) ); + } + + /** + * @since 1.9 + */ + public function testGetResults() { + + $expected = 'Lala'; + + $instance = $this->newInstance( $expected ); + $this->assertEquals( $expected, $instance->getResults( null ) ); + + } + + /** + * @since 1.9 + */ + public function testGetPageHeader() { + + $propertySearch = $this->newRandomString(); + + $context = $this->newContext( array( 'property' => $propertySearch ) ); + $context->setTitle( $this->newTitle() ); + + $instance = $this->newInstance(); + $instance->setContext( $context ); + $instance->getResults( null ); + + $reflector = $this->newReflector(); + $selectOptions = $reflector->getProperty( 'selectOptions' ); + $selectOptions->setAccessible( true ); + $selectOptions->setValue( $instance, array( + 'offset' => 1, + 'limit' => 2, + 'end' => 5, + 'count' => 4 + ) ); + + $matcher = array( + 'tag' => 'p', + 'attributes' => array( 'class' => 'smw-sp-properties-docu' ), + 'tag' => 'input', + 'attributes' => array( 'name' => 'property', 'value' => $propertySearch ), + 'tag' => 'input', + 'attributes' => array( 'type' => 'submit' ) + ); + + $this->assertTag( $matcher, $instance->getPageHeader() ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/querypages/QueryPageTest.php b/SemanticMediaWiki/tests/phpunit/includes/querypages/QueryPageTest.php new file mode 100644 index 00000000..852cc3c0 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/querypages/QueryPageTest.php @@ -0,0 +1,136 @@ +<?php + +namespace SMW\Test; + +/** + * Tests for the QueryPage class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\QueryPage + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class QueryPageTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\QueryPage'; + } + + /** + * Helper method that returns a QueryPage object + * + * @since 1.9 + * + * @param $result + * + * @return QueryPage + */ + private function newInstance( $search = '' ) { + + $queryPage = $this->getMockBuilder( $this->getClass() ) + ->setMethods( array( 'getResults', 'formatResult' ) ) + ->getMock(); + + $context = $this->newContext( array( 'property' => $search ) ); + $context->setTitle( $this->newTitle() ); + + $queryPage->setContext( $context ); + + return $queryPage; + } + + /** + * @test QueryPage::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @test QueryPage::linkParameters + * @dataProvider linkParametersDataProvider + * + * @since 1.9 + * + * @param $test + * @param $expected + */ + public function testLinkParameters( $test, $expected ) { + + $search = $this->newRandomString(); + $result = $this->newInstance( $test )->linkParameters(); + + $this->assertInternalType( 'array', $result ); + $this->assertEquals( $expected , $result ); + + } + + /** + * @test QueryPage::getSearchForm + * + * @since 1.9 + */ + public function testGetSearchForm() { + + $search = $this->newRandomString(); + $instance = $this->newInstance(); + + $reflector = $this->newReflector(); + $selectOptions = $reflector->getProperty( 'selectOptions' ); + $selectOptions->setAccessible( true ); + $selectOptions->setValue( $instance, array( + 'offset' => 1, + 'limit' => 2, + 'end' => 5, + 'count' => 4 + ) ); + + $result = $instance->getSearchForm( $search ); + + $matcher = array( + 'tag' => 'form', + 'descendant' => array( + 'tag' => 'input', + 'attributes' => array( 'name' => 'property', 'value' => $search ) + ) + ); + + $this->assertInternalType( 'string', $result ); + $this->assertTag( $matcher, $result ); + } + + /** + * Provides sample data to be tested + * + * @return array + */ + public function linkParametersDataProvider() { + $random = $this->newRandomString(); + + return array( + array( '' , array() ), + array( null , array() ), + array( $random , array( 'property' => $random ) ), + array( "[{$random}]" , array( 'property' => "[{$random}]" ) ), + array( "[&{$random}...]" , array( 'property' => "[&{$random}...]" ) ) + ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/querypages/UnusedPropertiesQueryPageTest.php b/SemanticMediaWiki/tests/phpunit/includes/querypages/UnusedPropertiesQueryPageTest.php new file mode 100644 index 00000000..df82b6f4 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/querypages/UnusedPropertiesQueryPageTest.php @@ -0,0 +1,174 @@ +<?php + +namespace SMW\Test; + +use SMW\UnusedPropertiesQueryPage; +use SMW\MessageFormatter; + +use SMWDataItem; + +/** + * @covers \SMW\UnusedPropertiesQueryPage + * @covers \SMW\QueryPage + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class UnusedPropertiesQueryPageTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\UnusedPropertiesQueryPage'; + } + + /** + * @since 1.9 + * + * @return DIWikiPage + */ + private function getMockDIWikiPage( $exists = true ) { + + $text = $this->newRandomString(); + + $title = $this->newMockBuilder()->newObject( 'Title', array( + 'exists' => $exists, + 'getText' => $text, + 'getNamespace' => NS_MAIN, + 'getPrefixedText' => $text + ) ); + + $diWikiPage = $this->newMockBuilder()->newObject( 'DIWikiPage', array( + 'getTitle' => $title, + ) ); + + return $diWikiPage; + } + + /** + * @since 1.9 + * + * @return UnusedPropertiesQueryPage + */ + private function newInstance( $result = null, $values = array() ) { + + $collector = $this->newMockBuilder()->newObject( 'CacheableResultCollector', array( + 'getResults' => $result + ) ); + + $mockStore = $this->newMockBuilder()->newObject( 'Store', array( + 'getPropertyValues' => $values, + 'getUnusedPropertiesSpecial' => $collector + ) ); + + $instance = new UnusedPropertiesQueryPage( $mockStore, $this->newSettings() ); + $instance->setContext( $this->newContext() ); + + return $instance; + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @dataProvider getUserDefinedDataProvider + * + * @since 1.9 + */ + public function testFormatResult( $isUserDefined ) { + + // Skin stub object + $skin = $this->getMock( 'Skin' ); + + // DIProperty + $instance = $this->newInstance(); + + $property = $this->newMockBuilder()->newObject( 'DIProperty', array( + 'isUserDefined' => $isUserDefined, + 'getDiWikiPage' => $this->getMockDIWikiPage( true ), + 'getLabel' => $this->newRandomString(), + ) ); + + $expected = $property->getDiWikiPage()->getTitle()->getText(); + $result = $instance->formatResult( $skin, $property ); + + $this->assertInternalType( 'string', $result ); + $this->assertContains( $expected, $result ); + + // Multiple entries + $instance = $this->newInstance(); + $multiple = array( $this->getMockDIWikiPage(), $this->getMockDIWikiPage() ); + + $property = $this->newMockBuilder()->newObject( 'DIProperty', array( + 'isUserDefined' => $isUserDefined, + 'getDiWikiPage' => $this->getMockDIWikiPage( true ), + 'getLabel' => $this->newRandomString(), + ) ); + + $expected = $property->getDiWikiPage()->getTitle()->getText(); + $instance = $this->newInstance( null, $multiple ); + + $result = $instance->formatResult( $skin, $property ); + + $this->assertInternalType( 'string', $result ); + $this->assertContains( $expected, $result ); + + // DIError + $instance = $this->newInstance(); + $error = $this->newRandomString(); + $diError = $this->newMockBuilder()->newObject( 'DIError', array( + 'getErrors' => $error + ) ); + + $result = $instance->formatResult( $skin, $diError ); + + $this->assertInternalType( 'string', $result ); + $this->assertContains( $error, $result ); + + } + + /** + * @since 1.9 + */ + public function testInvalidResultException() { + + $this->setExpectedException( '\SMW\InvalidResultException' ); + + $instance = $this->newInstance(); + $skin = $this->getMock( 'Skin' ); + + $this->assertInternalType( 'string', $instance->formatResult( $skin, null ) ); + + } + + /** + * @return array + */ + public function getUserDefinedDataProvider() { + return array( array( true ), array( false ) ); + } + + /** + * @since 1.9 + */ + public function testGetResults() { + + $expected = 'Lala'; + + $instance = $this->newInstance( $expected ); + $this->assertEquals( $expected, $instance->getResults( null ) ); + + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/querypages/WantedPropertiesQueryPageTest.php b/SemanticMediaWiki/tests/phpunit/includes/querypages/WantedPropertiesQueryPageTest.php new file mode 100644 index 00000000..10b9ab74 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/querypages/WantedPropertiesQueryPageTest.php @@ -0,0 +1,148 @@ +<?php + +namespace SMW\Test; + +use SMW\WantedPropertiesQueryPage; +use SMW\Settings; + +use SMWDataItem; + +/** + * @covers \SMW\WantedPropertiesQueryPage + * @covers \SMW\QueryPage + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class WantedPropertiesQueryPageTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\WantedPropertiesQueryPage'; + } + + /** + * @since 1.9 + * + * @return DIWikiPage + */ + private function getMockDIWikiPage( $exists = true ) { + + $text = $this->newRandomString(); + + $title = $this->newMockBuilder()->newObject( 'Title', array( + 'exists' => $exists, + 'getText' => $text, + 'getNamespace' => NS_MAIN, + 'getPrefixedText' => $text + ) ); + + $diWikiPage = $this->newMockBuilder()->newObject( 'DIWikiPage', array( + 'getTitle' => $title, + ) ); + + return $diWikiPage; + } + + /** + * @since 1.9 + * + * @return WantedPropertiesQueryPage + */ + private function newInstance( $result = null ) { + + $collector = $this->newMockBuilder()->newObject( 'CacheableResultCollector', array( + 'getResults' => $result + ) ); + + $mockStore = $this->newMockBuilder()->newObject( 'Store', array( + 'getPropertyValues' => array(), + 'getWantedPropertiesSpecial' => $collector + ) ); + + $instance = new WantedPropertiesQueryPage( $mockStore, $this->newSettings() ); + $instance->setContext( $this->newContext() ); + + return $instance; + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @dataProvider getUserDefinedDataProvider + * + * @since 1.9 + */ + public function testFormatResult( $isUserDefined ) { + + $instance = $this->newInstance(); + $skin = $this->getMock( 'Skin' ); + + $count = rand(); + $property = $this->newMockBuilder()->newObject( 'DIProperty', array( + 'isUserDefined' => $isUserDefined, + 'getDiWikiPage' => $this->getMockDIWikiPage( true ), + 'getLabel' => $this->newRandomString(), + ) ); + + $expected = $isUserDefined ? (string)$count : ''; + $result = $instance->formatResult( $skin, array( $property, $count ) ); + + $this->assertInternalType( 'string', $result ); + $isUserDefined ? $this->assertContains( $expected, $result ) : $this->assertEmpty( $result ); + + } + + /** + * @return array + */ + public function getUserDefinedDataProvider() { + return array( array( true ), array( false ) ); + } + + /** + * @since 1.9 + */ + public function testGetResults() { + + $expected = 'Lala'; + $instance = $this->newInstance( $expected ); + + $this->assertEquals( $expected, $instance->getResults( null ) ); + + } + + public function testFormatResultOnNonUserDefinedProperty() { + + $store = $this->getMockBuilder( '\SMW\Store' ) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $skin = $this->getMockBuilder( '\Skin' ) + ->disableOriginalConstructor() + ->getMock(); + + $setttings = Settings::newFromArray( array() ); + + $instance = new WantedPropertiesQueryPage( $store, $setttings ); + $result = $instance->formatResult( $skin, array( 'foo', 0 ) ); + + $this->assertInternalType( 'string', $result ); + $this->assertEmpty( $result ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/queryprinters/AggregatablePrinterTest.php b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/AggregatablePrinterTest.php new file mode 100644 index 00000000..97c3ccf6 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/AggregatablePrinterTest.php @@ -0,0 +1,286 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\Mock\MockObjectBuilder; +use SMW\Tests\Util\Mock\CoreMockObjectRepository; + +use SMWDataItem; +use SMWDINumber; + +use ReflectionClass; + +/** + * Tests for the AggregatablePrinter class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\AggregatablePrinter + * + * @ingroup QueryPrinterTest + * + * @group SMW + * @group SMWExtension + */ +class AggregatablePrinterTest extends QueryPrinterTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\AggregatablePrinter'; + } + + /** + * Helper method that returns a AggregatablePrinter object + * + * @return AggregatablePrinter + */ + private function newInstance( $parameters = array() ) { + return $this->setParameters( $this->getMockForAbstractClass( $this->getClass(), array( 'table' ) ), $parameters ); + } + + /** + * @test AggregatablePrinter::getResultText + * @dataProvider errorMessageProvider + * + * @since 1.9 + */ + public function testGetResultTextErrorMessage( $setup, $expected ) { + + $instance = $this->newInstance( $setup['parameters'] ); + $queryResult = $setup['queryResult']; + + $reflection = new ReflectionClass( '\SMW\AggregatablePrinter' ); + $method = $reflection->getMethod( 'getResultText' ); + $method->setAccessible( true ); + + $result = $method->invoke( $instance, $queryResult, SMW_OUTPUT_HTML ); + + $this->assertEmpty( $result ); + + foreach( $queryResult->getErrors() as $error ) { + $this->assertEquals( $expected['message'], $error ); + } + } + + /** + * @test AggregatablePrinter::addNumbersForDataItem + * + * @since 1.9 + */ + public function testAddNumbersForDataItem() { + + $values = array(); + $expected = array(); + $keys = array( 'test', 'foo', 'bar' ); + + $reflector = new ReflectionClass( '\SMW\AggregatablePrinter' ); + $method = $reflector->getMethod( 'addNumbersForDataItem' ); + $method->setAccessible( true ); + + for ( $i = 1; $i <= 10; $i++ ) { + + // Select random array key + $name = $keys[rand(0, 2)]; + + // Get a random number + $random = rand( 10, 500 ); + + // Set expected result and create dataItem + $expected[$name] = isset( $expected[$name] ) ? $expected[$name] + $random : $random; + $dataItem = new SMWDINumber( $random ); + + $this->assertEquals( $random, $dataItem->getNumber() ); + $this->assertEquals( SMWDataItem::TYPE_NUMBER, $dataItem->getDIType() ); + + // Invoke the instance + $result = $method->invokeArgs( $this->newInstance(), array( $dataItem, &$values, $name ) ); + + $this->assertInternalType( 'integer', $values[$name] ); + $this->assertEquals( $expected[$name], $values[$name] ); + } + } + + /** + * @test AggregatablePrinter::getNumericResults + * @dataProvider numberDataProvider + * + * @since 1.9 + */ + public function testGetNumericResults( $setup, $expected ) { + + $instance = $this->newInstance( $setup['parameters'] ); + + $reflector = new ReflectionClass( '\SMW\AggregatablePrinter' ); + $method = $reflector->getMethod( 'getNumericResults' ); + $method->setAccessible( true ); + + $result = $method->invoke( $instance, $setup['queryResult'], SMW_OUTPUT_HTML ); + + $this->assertInternalType( + 'array', + $result, + 'Asserts that getNumericResults() returns an array' + ); + + $this->assertEquals( + $expected['result'], + $result, + 'Asserts that the getNumericResults() output matches the expected result' + ); + + } + + /** + * @return array + */ + public function errorMessageProvider() { + + $mockBuilder = new MockObjectBuilder(); + $mockBuilder->registerRepository( new CoreMockObjectRepository() ); + + $message = wfMessage( 'smw-qp-aggregatable-empty-data' )->inContentLanguage()->text(); + + $provider = array(); + + $queryResult = $mockBuilder->newObject( 'QueryResult', array( + 'getErrors' => array( $message ) + ) ); + + $provider[] = array( + array( + 'parameters' => array( 'distribution' => true ), + 'queryResult' => $queryResult + ), + array( + 'message' => $message + ) + ); + + // #1 + $provider[] = array( + array( + 'parameters' => array( 'distribution' => false ), + 'queryResult' => $queryResult + ), + array( + 'message' => $message + ) + ); + return $provider; + } + + /** + * @return array + */ + public function numberDataProvider() { + + $provider = array(); + + $setup = array( + array( 'printRequest' => 'Foo', 'number' => 10, 'dataValue' => 'Quuey' ), + array( 'printRequest' => 'Bar', 'number' => 20, 'dataValue' => 'Quuey' ), + array( 'printRequest' => 'Bar', 'number' => 20, 'dataValue' => 'Xuuey' ) + ); + + // #0 aggregation = subject + $parameters = array( + 'headers' => SMW_HEADERS_PLAIN, + 'offset' => 0, + 'aggregation' => 'subject', + 'mainlabel' => '' + ); + + $provider[] = array( + array( + 'parameters' => $parameters, + 'queryResult' => $this->buildMockQueryResult( $setup ) + ), + array( + 'result' => array( 'Quuey' => 50 ) + ) + ); + + // #1 aggregation = property + $parameters = array( + 'headers' => SMW_HEADERS_PLAIN, + 'offset' => 0, + 'aggregation' => 'property', + 'mainlabel' => '' + ); + + $provider[] = array( + array( + 'parameters' => $parameters, + 'queryResult' => $this->buildMockQueryResult( $setup ) + ), + array( + 'result' => array( 'Foo' => 10, 'Bar' => 40 ) + ) + ); + + return $provider; + } + + /** + * @return QueryResult + */ + private function buildMockQueryResult( $setup ) { + + $mockBuilder = new MockObjectBuilder(); + $mockBuilder->registerRepository( new CoreMockObjectRepository() ); + + $printRequests = array(); + $resultArray = array(); + + foreach ( $setup as $value ) { + + $printRequest = $mockBuilder->newObject( 'PrintRequest', array( + 'getText' => $value['printRequest'], + 'getLabel' => $value['printRequest'] + ) ); + + $printRequests[] = $printRequest; + + $dataItem = $mockBuilder->newObject( 'DataItem', array( + 'getDIType' => SMWDataItem::TYPE_NUMBER, + 'getNumber' => $value['number'] + ) ); + + $dataValue = $mockBuilder->newObject( 'DataValue', array( + 'DataValueType' => 'SMWNumberValue', + 'getTypeID' => '_num', + 'getShortWikiText' => $value['dataValue'], + 'getDataItem' => $dataItem + ) ); + + $resultArray[] = $mockBuilder->newObject( 'ResultArray', array( + 'getText' => $value['printRequest'], + 'getPrintRequest' => $printRequest, + 'getNextDataValue' => $dataValue, + 'getNextDataItem' => $dataItem + ) ); + + } + + $queryResult = $mockBuilder->newObject( 'QueryResult', array( + 'getPrintRequests' => $printRequests, + 'getNext' => $resultArray, + 'getLink' => new \SMWInfolink( true, 'Lala' , 'Lula' ), + 'hasFurtherResults' => true + ) ); + + return $queryResult; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/queryprinters/CategoryResultPrinterTest.php b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/CategoryResultPrinterTest.php new file mode 100644 index 00000000..49cf2f2d --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/CategoryResultPrinterTest.php @@ -0,0 +1,42 @@ +<?php + +namespace SMW\Test; + +use SMW\CategoryResultPrinter; + +/** + * @covers \SMW\CategoryResultPrinter + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class CategoryResultPrinterTest extends QueryPrinterTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\CategoryResultPrinter'; + } + + /** + * @return CategoryResultPrinter + */ + private function getInstance( $parameters = array() ) { + return $this->setParameters( new CategoryResultPrinter( 'category' ), $parameters ); + } + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\CategoryResultPrinter', + $this->getInstance() + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/queryprinters/CsvResultPrinterTest.php b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/CsvResultPrinterTest.php new file mode 100644 index 00000000..9e9d628c --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/CsvResultPrinterTest.php @@ -0,0 +1,209 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\Mock\MockObjectBuilder; +use SMW\Tests\Util\Mock\CoreMockObjectRepository; + +use SMW\CsvResultPrinter; +use SMWDataItem; + +use ReflectionClass; + +/** + * Tests for the CsvResultPrinter class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\CsvResultPrinter + * + * @ingroup QueryPrinterTest + * + * @group SMW + * @group SMWExtension + */ +class CsvResultPrinterTest extends QueryPrinterTestCase { + + protected $mockBuilder; + + protected function setUp(){ + parent::setUp(); + + $this->mockBuilder = new MockObjectBuilder(); + $this->mockBuilder->registerRepository( new CoreMockObjectRepository() ); + } + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\CsvResultPrinter'; + } + + /** + * Helper method that returns a CsvResultPrinter object + * + * @return CsvResultPrinter + */ + private function newInstance( $parameters = array() ) { + return $this->setParameters( new CsvResultPrinter( 'csv' ), $parameters ); + } + + /** + * @test CsvResultPrinter::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @test CsvResultPrinter::getFileName + * + * @since 1.9 + */ + public function testGetFileName() { + + $filename = 'FooQueey'; + $instance = $this->newInstance( array( 'filename' => $filename ) ); + + $this->assertEquals( $filename, $instance->getFileName( $this->mockBuilder->newObject( 'QueryResult' ) ) ); + } + + /** + * @test CsvResultPrinter::getResultText + * @dataProvider resultDataProvider + * + * @since 1.9 + */ + public function testGetResultText( $setup, $expected ) { + + $instance = $this->newInstance( $setup['parameters'] ); + $reflector = new ReflectionClass( '\SMW\CsvResultPrinter' ); + + $property = $reflector->getProperty( 'fullParams' ); + $property->setAccessible( true ); + $property->setValue( $instance, array() ); + + $method = $reflector->getMethod( 'linkFurtherResults' ); + $method->setAccessible( true ); + $method->invoke( $instance, $setup['queryResult'] ); + + $method = $reflector->getMethod( 'getResultText' ); + $method->setAccessible( true ); + + $result = $method->invoke( $instance, $setup['queryResult'], $setup['outputMode'] ); + + $this->assertInternalType( + 'string', + $result, + 'Asserts that the result always returns a string' + ); + + $this->assertEquals( + $expected['result'], + $result, + 'Asserts that getResultText() yields the expected result' + ); + + } + + /** + * @return array + */ + public function resultDataProvider() { + + $provider = array(); + + $setup = array( + array( 'printRequest' => 'Foo', 'dataValue' => 'Quuey' ), + array( 'printRequest' => 'Bar', 'dataValue' => 'Quuey' ), + array( 'printRequest' => 'Bam', 'dataValue' => 'Xuuey' ) + ); + + // #0 + $parameters = array( + 'headers' => SMW_HEADERS_PLAIN, + 'format' => 'csv', + 'sep' => ',', + 'showsep' => false, + 'offset' => 0 + ); + + $provider[] = array( + array( + 'parameters' => $parameters, + 'queryResult' => $this->buildMockQueryResult( $setup ), + 'outputMode' => SMW_OUTPUT_FILE + ), + array( + 'result' => implode( ',', array( 'Foo', 'Bar', 'Bam' ) ) . "\n" . implode( ',', array( 'Quuey', 'Quuey', 'Xuuey' ) ) . "\n" + ) + ); + + return $provider; + + } + + /** + * @return QueryResult + */ + private function buildMockQueryResult( $setup ) { + + $mockBuilder = new MockObjectBuilder(); + $mockBuilder->registerRepository( new CoreMockObjectRepository() ); + + $printRequests = array(); + $resultArray = array(); + + foreach ( $setup as $value ) { + + $printRequest = $mockBuilder->newObject( 'PrintRequest', array( + 'getText' => $value['printRequest'], + 'getLabel' => $value['printRequest'] + ) ); + + $printRequests[] = $printRequest; + + $dataItem = $mockBuilder->newObject( 'DataItem', array( + 'getDIType' => SMWDataItem::TYPE_WIKIPAGE, + ) ); + + $dataValue = $mockBuilder->newObject( 'DataValue', array( + 'DataValueType' => 'SMWWikiPageValue', + 'getTypeID' => '_wpg', + 'getShortWikiText' => $value['dataValue'], + 'getWikiValue' => $value['dataValue'], + 'getDataItem' => $dataItem + ) ); + + $resultArray[] = $mockBuilder->newObject( 'ResultArray', array( + 'getText' => $value['printRequest'], + 'getPrintRequest' => $printRequest, + 'getNextDataValue' => $dataValue, + 'getNextDataItem' => $dataItem + ) ); + + } + + $queryResult = $mockBuilder->newObject( 'QueryResult', array( + 'getPrintRequests' => $printRequests, + 'getNext' => $resultArray, + 'getLink' => new \SMWInfolink( true, 'Lala' , 'Lula' ), + 'hasFurtherResults' => true + ) ); + + return $queryResult; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/queryprinters/DsvResultPrinterTest.php b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/DsvResultPrinterTest.php new file mode 100644 index 00000000..a6882db0 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/DsvResultPrinterTest.php @@ -0,0 +1,44 @@ +<?php + +namespace SMW\Test; + +use SMW\DsvResultPrinter; + +/** + * @covers \SMW\DsvResultPrinter + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class DsvResultPrinterTest extends QueryPrinterTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\DsvResultPrinter'; + } + + /** + * @return DsvResultPrinter + */ + private function getInstance( $parameters = array() ) { + return $this->setParameters( new DsvResultPrinter( 'dsv' ), $parameters ); + } + + public function testCanConstruc() { + + $this->assertInstanceOf( + '\SMW\DsvResultPrinter', + $this->getInstance() + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/queryprinters/EmbeddedResultPrinterTest.php b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/EmbeddedResultPrinterTest.php new file mode 100644 index 00000000..940b3f0c --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/EmbeddedResultPrinterTest.php @@ -0,0 +1,42 @@ +<?php + +namespace SMW\Test; + +use SMW\EmbeddedResultPrinter; + +/** + * @covers \SMW\EmbeddedResultPrinter + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class EmbeddedResultPrinterTest extends QueryPrinterTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\EmbeddedResultPrinter'; + } + + /** + * @return SMWEmbeddedResultPrinter + */ + private function getInstance( $parameters = array() ) { + return $this->setParameters( new EmbeddedResultPrinter( 'embedded' ), $parameters ); + } + + public function testcanConstruct() { + + $this->assertInstanceOf( + '\SMW\EmbeddedResultPrinter', + $this->getInstance() + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/queryprinters/FeedResultPrinterTest.php b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/FeedResultPrinterTest.php new file mode 100644 index 00000000..1fc9ad09 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/FeedResultPrinterTest.php @@ -0,0 +1,109 @@ +<?php + +namespace SMW\Test; + +use SMW\FeedResultPrinter; + +use ReflectionClass; + +/** + * Tests for the FeedResultPrinter class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\FeedResultPrinter + * + * @ingroup QueryPrinterTest + * + * @group SMW + * @group SMWExtension + */ +class FeedResultPrinterTest extends QueryPrinterTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\FeedResultPrinter'; + } + + /** + * Helper method that returns a FeedResultPrinter object + * + * @return FeedResultPrinter + */ + private function newInstance( $parameters = array() ) { + return $this->setParameters( new FeedResultPrinter( 'feed' ), $parameters ); + } + + /** + * @test FeedResultPrinter::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @test FeedResultPrinter::feedItemDescription + * @dataProvider textDataProvider + * + * @since 1.9 + */ + public function testFeedItemDescription( $setup, $expected, $message ) { + + $instance = $this->newInstance(); + + $reflector = new ReflectionClass( '\SMW\FeedResultPrinter' ); + $method = $reflector->getMethod( 'feedItemDescription' ); + $method->setAccessible( true ); + + $this->assertEquals( + $expected['text'], + $method->invoke( $instance, $setup['items'], $setup['pageContent'] ), + 'Failed asserting ' . $message['info'] + ); + + } + + + /** + * @return array + */ + public function textDataProvider() { + + $provider = array(); + + // #0 + // http://www.utexas.edu/learn/html/spchar.html + $provider[] = array( + array( + 'items' => array(), + 'pageContent' => 'Semantic MediaWiki Conference, have been announced: it will be held at' . + '[http://www.aohostels.com/en/tagungen/tagungen-berlin/ A&O Berlin Hauptbahnhof]' . + '&¢©«»—¡¿,åÃãÆç' + ), + array( + 'text' => 'Semantic MediaWiki Conference, have been announced: it will be held at' . + '[http://www.aohostels.com/en/tagungen/tagungen-berlin/ A&O Berlin Hauptbahnhof]' . + '&¢©«»—¡¿,åÃãÆç' + ), + array( 'info' => 'text enconding including html special characters' ) + ); + + return $provider; + + } + + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/queryprinters/JsonResultPrinterTest.php b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/JsonResultPrinterTest.php new file mode 100644 index 00000000..ab75bd35 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/JsonResultPrinterTest.php @@ -0,0 +1,133 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\Mock\MockObjectBuilder; +use SMW\Tests\Util\Mock\CoreMockObjectRepository; + +use SMW\JsonResultPrinter; +use SMW\ResultPrinter; + +use ReflectionClass; + +/** + * @covers \SMW\JsonResultPrinter + * + * @ingroup QueryPrinterTest + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class JsonResultPrinterTest extends QueryPrinterTestCase { + + protected $mockBuilder; + + protected function setUp(){ + parent::setUp(); + + $this->mockBuilder = new MockObjectBuilder(); + $this->mockBuilder->registerRepository( new CoreMockObjectRepository() ); + } + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\JsonResultPrinter'; + } + + /** + * @since 1.9 + * + * @return JsonResultPrinter + */ + private function newInstance( $parameters = array() ) { + return $this->setParameters( new JsonResultPrinter( 'json' ), $parameters ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testGetMimeType() { + + $this->assertEquals( + 'application/json', + $this->newInstance()->getMimeType( $this->mockBuilder->newObject( 'QueryResult' ) ), + 'Asserts that getMimeType() yields an expected result' + ); + + } + + /** + * @dataProvider filenameDataProvider + * + * @since 1.9 + */ + public function testGetFileName( $filename, $expected ) { + + $instance = $this->newInstance( array( 'searchlabel' => $filename ) ); + + $this->assertEquals( + $expected, + $instance->getFileName( $this->mockBuilder->newObject( 'QueryResult' ) ), + 'Asserts that getFileName() yields an expected result'); + } + + /** + * @return array + */ + public function filenameDataProvider() { + + $provider = array(); + + $provider[] = array( 'Lala', 'Lala.json' ); + $provider[] = array( 'Lala Lilu', 'Lala_Lilu.json' ); + $provider[] = array( '' , 'result.json'); + + return $provider; + } + + /** + * @since 1.9 + */ + public function testGetResultText() { + + $result = array( + 'lala' => __METHOD__, + 'lula' => 999388383838 + ); + + $expected = array_merge( $result, array( 'rows' => count( $result ) ) ); + + $instance = $this->newInstance( array( 'prettyprint' => false ) ); + + $reflector = new ReflectionClass( '\SMW\JsonResultPrinter' ); + $getResultText = $reflector->getMethod( 'getResultText' ); + $getResultText->setAccessible( true ); + + $queryResult = $this->mockBuilder->newObject( 'QueryResult', array( + 'serializeToArray' => $result, + 'getCount' => count( $result ) + ) ); + + $results = $getResultText->invoke( $instance, $queryResult, SMW_OUTPUT_FILE ); + + $this->assertInternalType( 'string', $results ); + $this->assertEquals( json_encode( $expected ), $results ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/queryprinters/RawResultPrinterTest.php b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/RawResultPrinterTest.php new file mode 100644 index 00000000..49bd85ea --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/RawResultPrinterTest.php @@ -0,0 +1,48 @@ +<?php + +namespace SMW\Test; + +use SMW\RawResultPrinter; + +/** + * @covers \SMW\RawResultPrinter + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class RawResultPrinterTest extends QueryPrinterTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\RawResultPrinter'; + } + + /** + * @return RawResultPrinter + */ + private function getInstance( $parameters = array() ) { + + $instance = $this->getMockBuilder( '\SMW\RawResultPrinter' ) + ->disableOriginalConstructor() + ->setConstructorArgs( array( 'api' ) ) + ->getMockForAbstractClass(); + + return $this->setParameters( $instance, $parameters ); + } + + public function testCanConstruct() { + + $this->assertInstanceOf( + '\SMW\RawResultPrinter', + $this->getInstance() + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/queryprinters/RdfResultPrinterTest.php b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/RdfResultPrinterTest.php new file mode 100644 index 00000000..5a4e9736 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/RdfResultPrinterTest.php @@ -0,0 +1,42 @@ +<?php + +namespace SMW\Test; + +use SMW\RdfResultPrinter; + +/** + * @covers \SMW\RdfResultPrinter + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class RdfResultPrinterTest extends QueryPrinterTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\RdfResultPrinter'; + } + + /** + * @return RdfResultPrinter + */ + private function getInstance( $parameters = array() ) { + return $this->setParameters( new RdfResultPrinter( 'rdf' ), $parameters ); + } + + public function testConstructor() { + + $this->assertInstanceOf( + '\SMW\RdfResultPrinter', + $this->getInstance() + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/queryprinters/ResultPrintersTest.php b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/ResultPrintersTest.php new file mode 100644 index 00000000..617c8a83 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/ResultPrintersTest.php @@ -0,0 +1,89 @@ +<?php + +namespace SMW\Test; + +use ParamProcessor\ParamDefinition; +use SMW\ResultPrinter; +use SMWQueryProcessor; + +/** + * Does some basic tests for the SMW\ResultPrinter deriving classes + * + * @since 1.9 + * + * @file + * + * @license GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ + +/** + * @covers \SMW\ResultPrinter + * + * @ingroup QueryPrinterTest + * + * @group SMW + * @group SMWExtension + */ +class ResultPrintersTest extends QueryPrinterTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return false; + } + + public function constructorProvider() { + global $smwgResultFormats; + + $formats = array(); + + foreach ( $smwgResultFormats as $format => $class ) { + $formats[] = array( $format, $class, true ); + $formats[] = array( $format, $class, false ); + } + + return $formats; + } + + /** + * @dataProvider constructorProvider + * + * @param string $format + * @param string $class + * @param boolean $isInline + */ + public function testConstructor( $format, $class, $isInline ) { + $instance = new $class( $format, $isInline ); + $this->assertInstanceOf( '\SMWIResultPrinter', $instance ); + } + + public function instanceProvider() { + global $smwgResultFormats; + + $instances = array(); + + foreach ( $smwgResultFormats as $format => $class ) { + $instances[] = new $class( $format, true ); + } + + return $this->arrayWrap( $instances ); + } + + /** + * @dataProvider instanceProvider + * + * @param \SMWResultPrinter $printer + */ + public function testGetParamDefinitions( ResultPrinter $printer ) { + $params = $printer->getParamDefinitions( SMWQueryProcessor::getParameters() ); + + $params = ParamDefinition::getCleanDefinitions( $params ); + + $this->assertInternalType( 'array', $params ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/queryprinters/TableResultPrinterTest.php b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/TableResultPrinterTest.php new file mode 100644 index 00000000..4e8a795a --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/queryprinters/TableResultPrinterTest.php @@ -0,0 +1,322 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\Mock\MockObjectBuilder; +use SMW\Tests\Util\Mock\CoreMockObjectRepository; + +use SMW\TableResultPrinter; +use SMW\DIWikiPage; + +use ReflectionClass; +use Title; + +/** + * Tests for the TableResultPrinter class + * + * @since 1.9 + * + * @file + * + * @license GNU GPL v2+ + * @author mwjames + */ + +/** + * @covers \SMW\TableResultPrinter + * + * @ingroup QueryPrinterTest + * + * @group SMW + * @group SMWExtension + */ +class TableResultPrinterTest extends QueryPrinterTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\TableResultPrinter'; + } + + /** + * Helper method that returns a TableResultPrinter object + * + * @return TableResultPrinter + */ + private function newInstance( $parameters = array() ) { + + $format = isset( $parameters['format'] ) ? $parameters['format'] : 'table'; + + return $this->setParameters( new TableResultPrinter( $format ), $parameters ); + } + + /** + * @test TableResultPrinter::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @test TableResultPrinter::getResultText + * @dataProvider standardTableDataProvider + * + * @since 1.9 + */ + public function testGetResultText( $setup, $expected ) { + + $instance = $this->newInstance( $setup['parameters'] ); + $reflector = new ReflectionClass( '\SMW\TableResultPrinter' ); + + $property = $reflector->getProperty( 'fullParams' ); + $property->setAccessible( true ); + $property->setValue( $instance, array() ); + + $method = $reflector->getMethod( 'linkFurtherResults' ); + $method->setAccessible( true ); + $method->invoke( $instance, $setup['queryResult'] ); + + $method = $reflector->getMethod( 'getResultText' ); + $method->setAccessible( true ); + + $result = $method->invoke( $instance, $setup['queryResult'], $setup['outputMode'] ); + + $this->assertInternalType( + 'string', + $result, + 'assert that the result always returns a string' + ); + + $this->assertTag( + $expected['matcher'], + $result, + 'asserts that tags correspond with invoked matcher' + ); + + } + + /** + * @return array + */ + public function standardTableDataProvider() { + + $mockBuilder = new MockObjectBuilder(); + $mockBuilder->registerRepository( new CoreMockObjectRepository() ); + + $provider = array(); + + $labels = array( + 'pr-1' => 'PrintRequest-PageValue', + 'pr-2' => 'PrintRequest-NumberValue', + 'ra-1' => 'ResultArray-PageValue', + 'ra-2' => 9001 + ); + + $printRequests = array(); + + $printRequests['pr-1'] = $mockBuilder->newObject( 'PrintRequest', array( + 'getText' => $labels['pr-1'] + ) ); + + $printRequests['pr-2'] = $mockBuilder->newObject( 'PrintRequest', array( + 'getText' => $labels['pr-2'] + ) ); + + $datItems = array(); + + $datItems['ra-1'] = DIWikiPage::newFromTitle( Title::newFromText( $labels['ra-1'], NS_MAIN ) ); + $datItems['ra-2'] = $mockBuilder->newObject( 'DataItem', array( 'getSortKey' => $labels['ra-2'] ) ); + + $dataValues = array(); + + $dataValues['ra-1'] = $mockBuilder->newObject( 'DataValue', array( + 'DataValueType' => 'SMWWikiPageValue', + 'getTypeID' => '_wpg', + 'getShortText' => $labels['ra-1'], + 'getDataItem' => $datItems['ra-1'] + ) ); + + $dataValues['ra-2'] = $mockBuilder->newObject( 'DataValue', array( + 'DataValueType' => 'SMWNumberValue', + 'getTypeID' => '_num', + 'getShortText' => $labels['ra-2'], + 'getDataItem' => $datItems['ra-2'] + ) ); + + $resultArray = array(); + + $resultArray['ra-1'] = $mockBuilder->newObject( 'ResultArray', array( + 'getText' => $labels['ra-1'], + 'getPrintRequest' => $printRequests['pr-1'], + 'getNextDataValue' => $dataValues['ra-1'], + ) ); + + $resultArray['ra-2'] = $mockBuilder->newObject( 'ResultArray', array( + 'getText' => $labels['ra-2'], + 'getPrintRequest' => $printRequests['pr-2'], + 'getNextDataValue' => $dataValues['ra-2'], + ) ); + + $queryResult = $mockBuilder->newObject( 'QueryResult', array( + 'getPrintRequests' => array( $printRequests['pr-1'], $printRequests['pr-2'] ), + 'getNext' => array( $resultArray['ra-1'], $resultArray['ra-2'] ), + 'getLink' => new \SMWInfolink( true, 'Lala' , 'Lula' ), + 'hasFurtherResults' => true + ) ); + + // #0 standard table + $parameters = array( + 'headers' => SMW_HEADERS_PLAIN, + 'class' => 'tableClass', + 'format' => 'table', + 'offset' => 0, + 'transpose' => false + ); + + $matcher = array( + 'tag' => 'table', 'attributes' => array( 'class' => $parameters['class'] ), + 'descendant' => array( + 'tag' => 'th', 'content' => $labels['pr-1'], 'attributes' => array( 'class' => $labels['pr-1'] ), + 'tag' => 'th', 'content' => $labels['pr-2'], 'attributes' => array( 'class' => $labels['pr-2'] ), + ), + 'descendant' => array( + 'tag' => 'tr', + 'child' => array( + 'tag' => 'td', 'content' => $labels['ra-1'], 'attributes' => array( 'class' => $labels['pr-1'] ), + 'tag' => 'td', 'content' => $labels['ra-2'], 'attributes' => array( 'class' => $labels['pr-2'] ) + ) + ), + 'descendant' => array( + 'tag' => 'tr', 'attributes' => array( 'class' => 'smwfooter' ), + 'child' => array( + 'tag' => 'td', 'attributes' => array( 'class' => 'sortbottom' ), + ) + ) + ); + + $provider[] = array( + array( + 'parameters' => $parameters, + 'queryResult' => $queryResult, + 'outputMode' => SMW_OUTPUT_FILE + ), + array( + 'matcher' => $matcher + ) + ); + + // #1 broadtable table + $parameters = array( + 'headers' => SMW_HEADERS_PLAIN, + 'class' => 'tableClass', + 'format' => 'broadtable', + 'offset' => 0, + 'transpose' => false + ); + + $matcher = array( + 'tag' => 'table', 'attributes' => array( 'class' => $parameters['class'], 'width' => '100%' ), + 'descendant' => array( + 'tag' => 'th', 'content' => $labels['pr-1'], 'attributes' => array( 'class' => $labels['pr-1'] ), + 'tag' => 'th', 'content' => $labels['pr-2'], 'attributes' => array( 'class' => $labels['pr-2'] ), + ), + 'descendant' => array( + 'tag' => 'tr', + 'child' => array( + 'tag' => 'td', 'content' => $labels['ra-1'], 'attributes' => array( 'class' => $labels['pr-1'] ), + 'tag' => 'td', 'content' => $labels['ra-2'], 'attributes' => array( 'class' => $labels['pr-2'] ) + ) + ), + 'descendant' => array( + 'tag' => 'tr', 'attributes' => array( 'class' => 'smwfooter' ), + 'child' => array( + 'tag' => 'td', 'attributes' => array( 'class' => 'sortbottom' ), + ) + ) + ); + + $provider[] = array( + array( + 'parameters' => $parameters, + 'queryResult' => $queryResult, + 'outputMode' => SMW_OUTPUT_FILE + ), + array( + 'matcher' => $matcher + ) + ); + + // #2 "headers=hide" + $parameters = array( + 'headers' => SMW_HEADERS_HIDE, + 'class' => 'tableClass', + 'format' => 'table', + 'offset' => 0, + 'transpose' => false + ); + + $matcher = array( + 'tag' => 'table', 'attributes' => array( 'class' => $parameters['class'] ), + 'descendant' => array( + 'tag' => 'th', 'content' => $labels['pr-1'], 'attributes' => array(), + 'tag' => 'th', 'content' => $labels['pr-2'], 'attributes' => array(), + ), + 'descendant' => array( + 'tag' => 'tr', + 'child' => array( + 'tag' => 'td', 'content' => $labels['ra-1'], 'attributes' => array(), + 'tag' => 'td', 'content' => $labels['ra-2'], 'attributes' => array() + ) + ), + 'descendant' => array( + 'tag' => 'tr', 'attributes' => array( 'class' => 'smwfooter' ), + 'child' => array( + 'tag' => 'td', 'attributes' => array( 'class' => 'sortbottom' ), + ) + ) + ); + + $provider[] = array( + array( + 'parameters' => $parameters, + 'queryResult' => $queryResult, + 'outputMode' => SMW_OUTPUT_FILE + ), + array( + 'matcher' => $matcher + ) + ); + + // #3 "transpose=true" + $parameters = array( + 'headers' => SMW_HEADERS_PLAIN, + 'class' => 'tableClass', + 'format' => 'table', + 'offset' => 0, + 'transpose' => true + ); + + //TODO add proper matching data, which I can't seem to get to work. + //MWJames would you mind doing the honors? + $matcher = array(); + + $provider[] = array( + array( + 'parameters' => $parameters, + 'queryResult' => $queryResult, + 'outputMode' => SMW_OUTPUT_FILE + ), + array( + 'matcher' => $matcher + ) + ); + + return $provider; + + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/serializer/QueryResultSerializerTest.php b/SemanticMediaWiki/tests/phpunit/includes/serializer/QueryResultSerializerTest.php new file mode 100644 index 00000000..d2db3bdc --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/serializer/QueryResultSerializerTest.php @@ -0,0 +1,181 @@ +<?php + +namespace SMW\Test; + +use SMW\Serializers\QueryResultSerializer; +use SMWQueryProcessor; +use SMWQueryResult; +use SMWDataItem as DataItem; + +/** + * @covers \SMW\Serializers\QueryResultSerializer + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class QueryResultSerializerTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string + */ + public function getClass() { + return '\SMW\Serializers\QueryResultSerializer'; + } + + /** + * Helper method that returns a QueryResultSerializer object + * + * @since 1.9 + */ + private function newSerializerInstance() { + return new QueryResultSerializer(); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newSerializerInstance() ); + } + + /** + * @since 1.9 + */ + public function testSerializeOutOfBoundsException() { + + $this->setExpectedException( 'OutOfBoundsException' ); + + $instance = $this->newSerializerInstance(); + $instance->serialize( 'Foo' ); + + } + + /** + * @dataProvider numberDataProvider + * + * @since 1.9 + */ + public function testQueryResultSerializerOnMock( $setup, $expected ) { + + $results = $this->newSerializerInstance()->serialize( $setup['queryResult'] ); + + $this->assertInternalType( 'array' , $results ); + $this->assertEquals( $expected['printrequests'], $results['printrequests'] ); + + } + + /** + * @since 1.9 + */ + public function testQueryResultSerializerOnMockOnDIWikiPageNonTitle() { + + $dataItem = $this->newMockBuilder()->newObject( 'DataItem', array( + 'getDIType' => DataItem::TYPE_WIKIPAGE, + 'getTitle' => null + ) ); + + $queryResult = $this->newMockBuilder()->newObject( 'QueryResult', array( + 'getPrintRequests' => array(), + 'getResults' => array( $dataItem ), + ) ); + + $results = $this->newSerializerInstance()->serialize( $queryResult ); + + $this->assertInternalType( 'array' , $results ); + $this->assertEmpty( $results['printrequests'] ); + $this->assertEmpty( $results['results'] ); + + } + + /** + * @return array + */ + public function numberDataProvider() { + + $provider = array(); + + $setup = array( + array( 'printRequest' => 'Foo-1', 'typeId' => '_num', 'number' => 10, 'dataValue' => 'Quuey' ), + array( 'printRequest' => 'Foo-2', 'typeId' => '_num', 'number' => 20, 'dataValue' => 'Vey' ), + ); + + $provider[] = array( + array( + 'queryResult' => $this->buildMockQueryResult( $setup ) + ), + array( + 'printrequests' => array( + array( 'label' => 'Foo-1', 'typeid' => '_num', 'mode' => 2, 'format' => false ), + array( 'label' => 'Foo-2', 'typeid' => '_num', 'mode' => 2, 'format' => false ) + ), + ) + ); + + return $provider; + } + + /** + * @return QueryResult + */ + private function buildMockQueryResult( $setup ) { + + $printRequests = array(); + $resultArray = array(); + $getResults = array(); + + foreach ( $setup as $value ) { + + $printRequest = $this->newMockBuilder()->newObject( 'PrintRequest', array( + 'getText' => $value['printRequest'], + 'getLabel' => $value['printRequest'], + 'getTypeID' => $value['typeId'], + 'getOutputFormat' => false + ) ); + + $printRequests[] = $printRequest; + $getResults[] = \SMW\DIWikipage::newFromTitle( $this->newTitle( NS_MAIN, $value['printRequest'] ) ); + + $dataItem = $this->newMockBuilder()->newObject( 'DataItem', array( + 'getDIType' => DataItem::TYPE_NUMBER, + 'getNumber' => $value['number'] + ) ); + + $dataValue = $this->newMockBuilder()->newObject( 'DataValue', array( + 'DataValueType' => 'SMWNumberValue', + 'getTypeID' => '_num', + 'getShortWikiText' => $value['dataValue'], + 'getDataItem' => $dataItem + ) ); + + $resultArray[] = $this->newMockBuilder()->newObject( 'ResultArray', array( + 'getText' => $value['printRequest'], + 'getPrintRequest' => $printRequest, + 'getNextDataValue' => $dataValue, + 'getNextDataItem' => $dataItem, + 'getContent' => $dataItem + ) ); + + } + + $queryResult = $this->newMockBuilder()->newObject( 'QueryResult', array( + 'getPrintRequests' => $printRequests, + 'getNext' => $resultArray, + 'getResults' => $getResults, + 'getStore' => $this->newMockBuilder()->newObject( 'Store' ), + 'getLink' => new \SMWInfolink( true, 'Lala' , 'Lula' ), + 'hasFurtherResults' => true + ) ); + + return $queryResult; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/serializer/SemanticDataDeserializerTest.php b/SemanticMediaWiki/tests/phpunit/includes/serializer/SemanticDataDeserializerTest.php new file mode 100644 index 00000000..8aaba903 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/serializer/SemanticDataDeserializerTest.php @@ -0,0 +1,97 @@ +<?php + +namespace SMW\Test; + +use SMW\Deserializers\SemanticDataDeserializer; + +/** + * @covers \SMW\Deserializers\SemanticDataDeserializer + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SemanticDataDeserializerTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\Deserializers\SemanticDataDeserializer'; + } + + /** + * Helper method that returns a SemanticDataDeserializer object + * + * @since 1.9 + */ + private function newDeserializerInstance() { + return new SemanticDataDeserializer(); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newDeserializerInstance() ); + } + + /** + * @since 1.9 + */ + public function testDeserializerInvalidVersionOutOfBoundsException() { + + $this->setExpectedException( 'OutOfBoundsException' ); + + $instance = $this->newDeserializerInstance(); + $instance->deserialize( array( 'version' => 'Foo' ) ); + + } + + /** + * @since 1.9 + */ + public function testDeserializerInvalidSubjectDataItemException() { + + $this->setExpectedException( '\SMW\DataItemException' ); + + $instance = $this->newDeserializerInstance(); + $instance->deserialize( array( 'subject' => '--#Foo' ) ); + + } + + /** + * @since 1.9 + */ + public function testDeserializerMissingSubjectOutOfBoundsException() { + + $this->setExpectedException( 'OutOfBoundsException' ); + + $instance = $this->newDeserializerInstance(); + $instance->deserialize( array() ); + + } + + /** + * @since 1.9 + */ + public function testDeserializerSubjectWithoutData() { + + $instance = $this->newDeserializerInstance(); + + $this->assertInstanceOf( + 'SMW\SemanticData', + $instance->deserialize( array( 'subject' => 'Foo#0#' ) ) + ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/serializer/SemanticDataSerializerDeserializerRoundtripTest.php b/SemanticMediaWiki/tests/phpunit/includes/serializer/SemanticDataSerializerDeserializerRoundtripTest.php new file mode 100644 index 00000000..cb9b9dd4 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/serializer/SemanticDataSerializerDeserializerRoundtripTest.php @@ -0,0 +1,242 @@ +<?php + +namespace SMW\Test; + +use SMW\Deserializers\SemanticDataDeserializer; +use SMW\Serializers\SemanticDataSerializer; + +use SMW\DataValueFactory; +use SMw\SemanticData; +use SMW\DIWikiPage; +use SMW\Subobject; + +/** + * @covers \SMW\Deserializers\SemanticDataDeserializer + * @covers \SMW\Serializers\SemanticDataSerializer + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SemanticDataSerializerDeserializerRoundtripTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return false; + } + + /** + * Helper method that returns a SemanticDataSerializer object + * + * @since 1.9 + */ + private function newSerializerInstance() { + return new SemanticDataSerializer(); + } + + /** + * Helper method that returns a SemanticDataDeserializer object + * + * @since 1.9 + */ + private function newDeserializerInstance() { + return new SemanticDataDeserializer(); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( '\SMW\Serializers\SemanticDataSerializer', $this->newSerializerInstance() ); + $this->assertInstanceOf( '\SMW\Deserializers\SemanticDataDeserializer', $this->newDeserializerInstance() ); + } + + /** + * @dataProvider semanticDataProvider + * + * @since 1.9 + */ + public function testSerializerDeserializerRountrip( $data ) { + + $serialized = $this->newSerializerInstance()->serialize( $data ); + + $this->assertEquals( + $serialized, + $this->newSerializerInstance()->serialize( $this->newDeserializerInstance()->deserialize( $serialized ) ), + 'Asserts that the intial serialized container is equal to a container after a roundtrip' + ); + + + $this->assertEquals( + $data->getHash(), + $this->newDeserializerInstance()->deserialize( $serialized )->getHash(), + 'Asserts that the hash of the orginal SemanticData container equals that of the serialized-un-serialized container' + ); + } + + /** + * @dataProvider incompleteSubobjectDataProvider + * + * @since 1.9.0.2 + */ + public function testSerializerDeserializerWithIncompleteSubobjectData( $data ) { + + $serialized = $this->newSerializerInstance()->serialize( $data ); + + $this->assertInstanceOf( + 'SMW\SemanticData', + $this->newDeserializerInstance()->deserialize( $serialized ), + 'Asserts that SemanticData instance is returned for an incomplete data set' + ); + + } + + /** + * @dataProvider typeChangeSemanticDataProvider + * + * @since 1.9 + */ + public function testForcedTypeErrorDuringRountrip( $data, $type ) { + + $serialized = $this->newSerializerInstance()->serialize( $data ); + $deserializer = $this->newDeserializerInstance(); + + // Injects a different type to cause an error (this would normally + // happen when a property definition is changed such as page -> text + // etc.) + $reflector = $this->newReflector( '\SMW\Deserializers\SemanticDataDeserializer' ); + $property = $reflector->getProperty( 'dataItemTypeIdCache' ); + $property->setAccessible( true ); + $property->setValue( $deserializer, array( $type => 2 ) ); + + $deserialized = $deserializer->deserialize( $serialized ); + + $this->assertInstanceOf( + 'SMW\SemanticData', + $deserialized, + 'Asserts the instance' + ); + + $this->assertNotEmpty( + $deserialized->getErrors(), + 'Asserts that getErrors() returns not empty' + ); + + } + + /** + * @return array + */ + public function semanticDataProvider() { + + $provider = array(); + $title = $this->newTitle( NS_MAIN, 'Foo' ); + + // #0 Empty container + $foo = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + $provider[] = array( $foo ); + + // #1 Single entry + $foo = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + $foo->addDataValue( DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Bar' ) ); + $provider[] = array( $foo ); + + // #2 Single + single subobject entry + $foo = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + $foo->addDataValue( DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Bar' ) ); + + $subobject = new Subobject( $title ); + $subobject->setSemanticData( 'Foo' ); + $subobject->addDataValue( DataValueFactory::getInstance()->newPropertyValue( 'Has subobjects', 'Bam' ) ); + + $foo->addPropertyObjectValue( $subobject->getProperty(), $subobject->getContainer() ); + + $provider[] = array( $foo ); + + // #3 Multiple entries + $foo = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + $foo->addDataValue( DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Bar' ) ); + $foo->addDataValue( DataValueFactory::getInstance()->newPropertyValue( 'Has queez', 'Xeey' ) ); + + $subobject = new Subobject( $title ); + $subobject->setSemanticData( 'Foo' ); + $subobject->addDataValue( DataValueFactory::getInstance()->newPropertyValue( 'Has subobjects', 'Bam' ) ); + $subobject->addDataValue( DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Fuz' ) ); + + $subobject->setSemanticData( 'Bar' ); + $subobject->addDataValue( DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Fuz' ) ); + + $foo->addPropertyObjectValue( $subobject->getProperty(), $subobject->getContainer() ); + + $provider[] = array( $foo ); + + return $provider; + } + + /** + * @return array + */ + public function incompleteSubobjectDataProvider() { + + $provider = array(); + + $title = $this->newTitle( NS_MAIN, 'Foo' ); + + $subobject = new Subobject( $title ); + $subobject->setSemanticData( 'Foo' ); + + $foo = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + $foo->addDataValue( DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Bar' ) ); + $foo->addPropertyObjectValue( $subobject->getProperty(), $subobject->getSemanticData()->getSubject() ); + + $provider[] = array( $foo ); + + return $provider; + } + + /** + * @return array + */ + public function typeChangeSemanticDataProvider() { + + $provider = array(); + $title = $this->newTitle( NS_MAIN, 'Foo' ); + + // #0 Single entry + $foo = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + $foo->addDataValue( DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Bar' ) ); + + $provider[] = array( $foo, 'Has_fooQuex' ); + + // #1 Single subobject entry + $foo = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + + $subobject = new Subobject( $title ); + $subobject->setSemanticData( 'Foo' ); + $subobject->addDataValue( DataValueFactory::getInstance()->newPropertyValue( 'Has fomQuex', 'Bam' ) ); + + $foo->addPropertyObjectValue( $subobject->getProperty(), $subobject->getContainer() ); + + $provider[] = array( $foo, 'Has_fomQuex' ); + + // #2 Combined + $foo = new SemanticData( DIWikiPage::newFromTitle( $title ) ); + $foo->addDataValue( DataValueFactory::getInstance()->newPropertyValue( 'Has fooQuex', 'Bar' ) ); + $foo->addPropertyObjectValue( $subobject->getProperty(), $subobject->getContainer() ); + + $provider[] = array( $foo, 'Has_fomQuex' ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/serializer/SemanticDataSerializerTest.php b/SemanticMediaWiki/tests/phpunit/includes/serializer/SemanticDataSerializerTest.php new file mode 100644 index 00000000..acfabd16 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/serializer/SemanticDataSerializerTest.php @@ -0,0 +1,117 @@ +<?php + +namespace SMW\Tests\Serializers; + +use SMW\Serializers\SemanticDataSerializer; + +use SMW\Tests\Util\SemanticDataFactory; + +use SMW\DataValueFactory; +use SMw\SemanticData; +use SMW\DIWikiPage; +use SMW\Subobject; + +use Title; + +/** + * @covers \SMW\Serializers\SemanticDataSerializer + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SemanticDataSerializerTest extends \PHPUnit_Framework_TestCase { + + private $dataValueFactory; + private $semanticDataFactory; + + public function testCanConstructor() { + + $this->assertInstanceOf( + '\SMW\Serializers\SemanticDataSerializer', + new SemanticDataSerializer() + ); + } + + public function testInvalidSerializerObjectThrowsException() { + + $this->setExpectedException( 'OutOfBoundsException' ); + + $instance = new SemanticDataSerializer(); + $instance->serialize( 'Foo' ); + } + + /** + * @dataProvider semanticDataProvider + */ + public function testSerializerDeserializerRountrip( $data ) { + + $instance = new SemanticDataSerializer(); + + $this->assertInternalType( + 'array', + $instance->serialize( $data ) + ); + } + + public function semanticDataProvider() { + + $this->semanticDataFactory = new SemanticDataFactory(); + $this->dataValueFactory = DataValueFactory::getInstance(); + + $title = Title::newFromText( 'Foo' ); + + #0 Empty container + $foo = $this->semanticDataFactory->setSubject( DIWikiPage::newFromTitle( $title ) )->newEmptySemanticData(); + $provider[] = array( $foo ); + + #1 Single entry + $foo = $this->semanticDataFactory->setSubject( DIWikiPage::newFromTitle( $title ) )->newEmptySemanticData(); + $foo->addDataValue( $this->dataValueFactory->newPropertyValue( 'Has fooQuex', 'Bar' ) ); + $provider[] = array( $foo ); + + // #2 Single + single subobject entry + $foo = $this->semanticDataFactory->setSubject( DIWikiPage::newFromTitle( $title ) )->newEmptySemanticData(); + $foo->addDataValue( $this->dataValueFactory->newPropertyValue( 'Has fooQuex', 'Bar' ) ); + + $subobject = new Subobject( $title ); + $subobject->setSemanticData( 'Foo' ); + $subobject->addDataValue( $this->dataValueFactory->newPropertyValue( 'Has subobjects', 'Bam' ) ); + + $foo->addPropertyObjectValue( + $subobject->getProperty(), + $subobject->getContainer() + ); + + $provider[] = array( $foo ); + + #3 Multiple entries + $foo = $this->semanticDataFactory->setSubject( DIWikiPage::newFromTitle( $title ) )->newEmptySemanticData(); + $foo->addDataValue( $this->dataValueFactory->newPropertyValue( 'Has fooQuex', 'Bar' ) ); + $foo->addDataValue( $this->dataValueFactory->newPropertyValue( 'Has queez', 'Xeey' ) ); + + $subobject = new Subobject( $title ); + $subobject->setSemanticData( 'Foo' ); + $subobject->addDataValue( $this->dataValueFactory->newPropertyValue( 'Has subobjects', 'Bam' ) ); + $subobject->addDataValue( $this->dataValueFactory->newPropertyValue( 'Has fooQuex', 'Fuz' ) ); + + $subobject->setSemanticData( 'Bar' ); + $subobject->addDataValue( $this->dataValueFactory->newPropertyValue( 'Has fooQuex', 'Fuz' ) ); + + $foo->addPropertyObjectValue( + $subobject->getProperty(), + $subobject->getContainer() + ); + + $provider[] = array( $foo ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/serializer/SerializerFactoryTest.php b/SemanticMediaWiki/tests/phpunit/includes/serializer/SerializerFactoryTest.php new file mode 100644 index 00000000..77938e64 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/serializer/SerializerFactoryTest.php @@ -0,0 +1,142 @@ +<?php + +namespace SMW\Test; + +use SMW\SerializerFactory; +use SMw\SemanticData; +use SMW\DIWikiPage; + +/** + * @covers \SMW\SerializerFactory + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SerializerFactoryTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\SerializerFactory'; + } + + /** + * @since 1.9 + */ + public function testUnregisteredSerializeObjectOutOfBoundsException() { + + $this->setExpectedException( 'OutOfBoundsException' ); + + SerializerFactory::serialize( 'Foo' ); + + } + + /** + * @dataProvider exceptionDataProvider + * @since 1.9 + */ + public function testUnregisteredDeserializerObjectOutOfBoundsException( $setup ) { + + $this->setExpectedException( 'OutOfBoundsException' ); + + SerializerFactory::deserialize( $setup ); + + } + + /** + * @dataProvider serializerDataProvider + * + * @since 1.9 + */ + public function testRegisteredSerializerFactory( $object ) { + + $serialized = SerializerFactory::serialize( $object ); + + $this->assertInternalType( + 'array', + $serialized, + 'Asserts that serialize() returns an array' + ); + + } + + /** + * @dataProvider deserializerDataProvider + * + * @since 1.9 + */ + public function testRegisteredDeserializerFactory( $object, $instance ) { + + $unserialized = SerializerFactory::deserialize( $object ); + + $this->assertInstanceOf( + $instance, + $unserialized, + "Asserts that deserialize() returns a {$instance} instance" + ); + + } + + /** + * @return array + */ + public function exceptionDataProvider() { + + $provider = array(); + + // #0 + $provider[] = array( array() ); + + // #1 + $provider[] = array( array( 'serializer' => 'Foo' ) ); + + return $provider; + } + + /** + * @return array + */ + public function serializerDataProvider() { + + $provider = array(); + + // #0 SemanticData + $provider[] = array( + new SemanticData( DIWikiPage::newFromTitle( $this->newTitle() ) ), + ); + + // #1 QueryResult + $provider[] = array( + $this->newMockBuilder()->newObject( 'QueryResult', array( + 'getResults' => array(), + 'getPrintRequests' => array() + ) ) + ); + + return $provider; + } + + /** + * @return array + */ + public function deserializerDataProvider() { + + $provider = array(); + + // #0 SemanticData + $provider[] = array( array( 'serializer' => 'SMW\Serializers\SemanticDataSerializer', 'subject' => 'Foo#0#' ), '\SMW\SemanticData' ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/specials/SpecialConceptsTest.php b/SemanticMediaWiki/tests/phpunit/includes/specials/SpecialConceptsTest.php new file mode 100644 index 00000000..85b53011 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/specials/SpecialConceptsTest.php @@ -0,0 +1,94 @@ +<?php + +namespace SMW\Test; + +use SMW\SpecialConcepts; +use SMW\DIWikiPage; +use SMWDataItem; + +use Title; + +/** + * @covers SMW\SpecialConcepts + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group SpecialPage + * @group medium + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SpecialConceptsTest extends SpecialPageTestCase { + + public function getClass() { + return '\SMW\SpecialConcepts'; + } + + /** + * @return SpecialConcepts + */ + protected function getInstance() { + return new SpecialConcepts(); + } + + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), $this->getInstance() ); + } + + public function testExecute() { + + $this->execute(); + + $matches = array( + 'tag' => 'span', + 'attributes' => array( 'class' => 'smw-sp-concept-docu' ) + ); + + $this->assertTag( $matches, $this->getText() ); + } + + /** + * @depends testExecute + */ + public function testGetHtmlForAnEmptySubject() { + + $instance = $this->getInstance(); + + $matches = array( + 'tag' => 'span', + 'attributes' => array( 'class' => 'smw-sp-concept-empty' ) + ); + + $this->assertTag( + $matches, + $instance->getHtml( array(), 0, 0, 0 ) + ); + + } + + /** + * @depends testGetHtmlForAnEmptySubject + */ + public function testGetHtmlForSingleSubject() { + + $subject = DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ); + $instance = $this->getInstance(); + + $matches = array( + 'tag' => 'span', + 'attributes' => array( 'class' => 'smw-sp-concept-count' ) + ); + + $this->assertTag( + $matches, + $instance->getHtml( array( $subject ), 1, 1, 1 ) + ); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/specials/SpecialSMWAdminTest.php b/SemanticMediaWiki/tests/phpunit/includes/specials/SpecialSMWAdminTest.php new file mode 100644 index 00000000..3b530b71 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/specials/SpecialSMWAdminTest.php @@ -0,0 +1,110 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\Util\Mock\MockSuperUser; + +use SMWAdmin; +use FauxRequest; +use User; + +/** + * @covers \SMWAdmin + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group SpecialPage + * @group medium + * + * @licence GNU GPL v2+ + * @since 1.9.0.2 + * + * @author mwjames + */ +class SpecialSMWAdminTest extends SpecialPageTestCase { + + public function getClass() { + return '\SMWAdmin'; + } + + protected function getInstance() { + return new SMWAdmin(); + } + + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), $this->getInstance() ); + } + + public function testExecuteWithMissingPermissionThrowsException() { + + $this->setExpectedException( 'PermissionsError' ); + $this->execute( '', null, new User ); + } + + public function testExecute() { + + $this->execute( '', null, new MockSuperUser ); + $this->assertInternalType( 'string', $this->getText() ); + } + + /** + * @depends testExecute + */ + public function testExecuteOnActionListSettings() { + + $this->execute( '', new FauxRequest( array( 'action' => 'listsettings' ) ), new MockSuperUser ); + $this->assertInternalType( 'string', $this->getText() ); + } + + /** + * @depends testExecute + */ + public function testExecuteOnIdLookup() { + + $fakeIdTableClass = $this->getMockBuilder( '\stdClass' ) + ->disableOriginalConstructor() + ->setMethods( array( 'getIdTable' ) ) + ->getMock(); + + $fakeIdTableClass->expects( $this->atLeastOnce() ) + ->method( 'getIdTable' ) + ->will( $this->returnValue( 'fake_foo_table' ) ); + + $selectRow = new \stdClass; + $selectRow->smw_title = 'Queey'; + + $database = $this->getMockBuilder( 'SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->once() ) + ->method( 'selectRow' ) + ->with( $this->equalTo( 'fake_foo_table' ) ) + ->will( $this->returnValue( $selectRow ) ); + + $store = $this->getMockBuilder( 'SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $store->expects( $this->once() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $store->expects( $this->once() ) + ->method( 'getObjectIds' ) + ->will( $this->returnValue( $fakeIdTableClass ) ); + + $this->setStore( $store ); + $this->execute( '', new FauxRequest( + array( + 'action' => 'idlookup', + 'objectId' => '9999' + ) ), new MockSuperUser + ); + + $this->assertInternalType( 'string', $this->getText() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/specials/SpecialsTest.php b/SemanticMediaWiki/tests/phpunit/includes/specials/SpecialsTest.php new file mode 100644 index 00000000..e171c8e2 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/specials/SpecialsTest.php @@ -0,0 +1,160 @@ +<?php + +namespace SMW\Test; + +use SpecialPageFactory; +use RequestContext; +use FauxRequest; +use SpecialPage; +use Language; + +/** + * Tests for registered special pages + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + * @author mwjames + */ + +/** + * @covers \SMW\SpecialSemanticStatistics + * @covers \SMW\SpecialWantedProperties + * @covers \SMW\SpecialUnusedProperties + * @covers \SMW\SpecialProperties + * @covers \SMW\SpecialConcepts + * @covers \SMW\SpecialPage + * @covers SMWAskPage + * @covers SMWSpecialBrowse + * @covers SMWAdmin + * @covers SMWSearchByProperty + * + * @note Test base was borrowed from the EducationProgram extension + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group medium + */ +class SpecialsTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return false; + } + + /** + * @dataProvider specialPageProvider + * + * @param $specialPage + */ + public function testSpecial( SpecialPage $specialPage ) { + + try { + $specialPage->execute( '' ); + } + catch ( \Exception $exception ) { + if ( !( $exception instanceof \PermissionsError ) && !( $exception instanceof \ErrorPageError ) ) { + throw $exception; + } + } + + $this->assertTrue( true, 'SpecialPage test did run without errors' ); + } + + /** + * @test SpecialPageFactory::getLocalNameFor + * @dataProvider specialPageProvider + * + * Test created in response to bug 44191 + * + * @param $specialPage + */ + public function testSpecialAliasesContLang( SpecialPage $specialPage ) { + + // Test for languages + $langCodes = array( 'en', 'fr', 'de', 'es', 'zh', 'ja' ); + + // Test aliases for a specific language + foreach ( $langCodes as $langCode ) { + $langObj = Language::factory( $langCode ); + $aliases = $langObj->getSpecialPageAliases(); + $found = false; + $name = $specialPage->getName(); + + // Check against available aliases + foreach ( $aliases as $n => $values ) { + foreach ( $values as $value ) { + if( $name === $value ) { + $found = true; + break; + } + } + } + + $this->assertTrue( $found, "{$name} alias not found in language {$langCode}" ); + } + } + + /** + * Provides special pages + * + * @return array + */ + public function specialPageProvider() { + $request = new FauxRequest( array(), true ); + $argLists = array(); + + $specialPages = array( + 'Ask', + 'Browse', + 'PageProperty', + 'SearchByProperty', + 'SMWAdmin', + 'SemanticStatistics', + 'ExportRDF', + 'Types', + 'Properties', + 'UnusedProperties', + 'WantedProperties', + 'Concepts' + + // Can't be tested because of + + // FIXME Test fails with Undefined index: HTTP_ACCEPT + // 'URIResolver' + + ); + + foreach ( $specialPages as $special ) { + + if ( array_key_exists( $special, $GLOBALS['wgSpecialPages'] ) ) { + + $specialPage = SpecialPageFactory::getPage( $special ); + + // Deprecated: Use of SpecialPage::getTitle was deprecated in MediaWiki 1.23 + $title = method_exists( $specialPage, 'getPageTitle') ? $specialPage->getPageTitle() : $specialPage->getTitle(); + + $context = RequestContext::newExtraneousContext( $title ); + $context->setRequest( $request ); + + $specialPage->setContext( clone $context ); + $argLists[] = array( clone $specialPage ); + + $context->setUser( $this->getUser() ); + $specialPage->setContext( $context ); + $argLists[] = array( $specialPage ); + } + } + + return $argLists; + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/CacheableResultCollectorTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/CacheableResultCollectorTest.php new file mode 100644 index 00000000..9942b41c --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/CacheableResultCollectorTest.php @@ -0,0 +1,150 @@ +<?php + +namespace SMW\Test; + +use SMW\SimpleDictionary; + +use SMWRequestOptions; + +/** + * @covers \SMW\Store\CacheableResultCollector + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class CacheableResultCollectorTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\Store\CacheableResultCollector'; + } + + /** + * @since 1.9 + * + * @return CacheableResultCollector + */ + private function getInstance( $doCollect = array(), $cacheSetup = array() ) { + + $collector = $this->newMockBuilder()->newObject( 'CacheableResultCollector', array( + 'runCollector' => $doCollect, + 'cacheSetup' => new SimpleDictionary( $cacheSetup ) + ) ); + + return $collector; + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->getInstance() ); + } + + /** + * @dataProvider resultDataProvider + * + * @since 1.9 + */ + public function testGetResults( $setup, $expected ) { + + $instance = $this->getInstance( $setup['test'], $setup['cacheSetup'] ); + $instance->setRequestOptions( new SMWRequestOptions() ); + + $result = $instance->getResults(); + + $this->assertInternalType( 'array', $result ); + $this->assertInternalType( $expected['cacheDate'], $instance->getCacheDate() ); + $this->assertEquals( $expected['isCached'], $instance->isCached() ); + $this->assertEquals( $expected['result'], $result ); + $this->assertEquals( $expected['count'], $instance->getCount() ); + + } + + /** + * @var array + */ + public function resultDataProvider() { + + $provider = array(); + + $result = array( $this->newRandomString() ); + + // #0 Non-cached scenario + $provider[] = array( + array( + 'test' => $result, + 'cacheSetup' => array( + 'id' => rand(), + 'type' => false, + 'enabled' => false, + 'expiry' => 100, + ) + ), + array( + 'result' => $result, + 'cacheDate' => 'null', + 'isCached' => false, + 'count' => count( $result ) + ) + ); + + // #1 Cached scenario + $id = rand(); + $result = array( $this->newRandomString(), $this->newRandomString() ); + + $provider[] = array( + array( + 'test' => $result, + 'cacheSetup' => array( + 'id' => $id, + 'type' => 'hash', + 'enabled' => true, + 'expiry' => 100, + ) + ), + array( + 'result' => $result, + 'cacheDate' => 'null', + 'isCached' => false, + 'count' => count( $result ) + ) + ); + + // #2 Initialized with a different 'nonRelevant' set, id is kept + // the same and results are expected to be equal with the previous + // initialization (cached results) + $nonRelevant = array( 'Lula' ); + + $provider[] = array( + array( + 'test' => $nonRelevant, + 'cacheSetup' => array( + 'id' => $id, + 'type' => 'hash', + 'enabled' => true, + 'expiry' => 100, + ) + ), + array( + 'result' => $result, + 'cacheDate' => 'string', + 'isCached' => true, + 'count' => count( $result ) + ) + ); + + return $provider; + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/QueryOutputFormatterTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/QueryOutputFormatterTest.php new file mode 100644 index 00000000..9bd32c63 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/QueryOutputFormatterTest.php @@ -0,0 +1,46 @@ +<?php + +namespace SMW\Tests; + +use SMW\QueryOutputFormatter; + +use SMWQuery as Query; + +/** + * @covers \SMW\QueryOutputFormatter + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 2.0 + * + * @author mwjames + */ +class QueryOutputFormatterTest extends \PHPUnit_Framework_TestCase { + + public function testFormatDebugOutputWithoutQuery() { + + $instance = new QueryOutputFormatter(); + + $this->assertInternalType( + 'string', + $instance->formatDebugOutput( 'foo', array(), null ) + ); + } + + public function testFormatDebugOutputWithQuery() { + + $description = $this->getMockForAbstractClass( '\SMWDescription' ); + + $instance = new QueryOutputFormatter(); + + $this->assertInternalType( + 'string', + $instance->formatDebugOutput( 'foo', array(), new Query( $description ) ) + ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/StoreFactoryTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/StoreFactoryTest.php new file mode 100644 index 00000000..56b458ea --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/StoreFactoryTest.php @@ -0,0 +1,98 @@ +<?php + +namespace SMW\Tests; + +use SMW\StoreFactory; +use SMW\Settings; + +/** + * @covers \SMW\StoreFactory + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class StoreFactoryTest extends \PHPUnit_Framework_TestCase { + + protected function tearDown() { + StoreFactory::clear(); + + parent::tearDown(); + } + + public function testGetDefaultStore() { + + $instance = StoreFactory::getStore(); + + $this->assertInstanceOf( + Settings::newFromGlobals()->get( 'smwgDefaultStore' ), + $instance + ); + + $this->assertSame( + StoreFactory::getStore(), + $instance + ); + + StoreFactory::clear(); + + $this->assertNotSame( + StoreFactory::getStore(), + $instance + ); + } + + public function testDifferentStoreIdInstanceInvocation() { + + $this->assertInstanceOf( 'SMW\Store', StoreFactory::getStore( '\SMWSQLStore3' ) ); + $this->assertInstanceOf( 'SMW\Store', StoreFactory::getStore( '\SMWSparqlStore' ) ); + + $this->assertNotSame( + StoreFactory::getStore( '\SMWSQLStore3' ), + StoreFactory::getStore( '\SMWSparqlStore' ) + ); + } + + public function testSetDefaultStoreForUnitTest() { + + $store = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + StoreFactory::setDefaultStoreForUnitTest( $store ); + + $this->assertSame( + $store, + StoreFactory::getStore() + ); + } + + public function testStoreInstanceException() { + $this->setExpectedException( '\SMW\InvalidStoreException' ); + StoreFactory::getStore( '\SMW\StoreFactory' ); + } + + public function testStoreWithInvalidClassThrowsException() { + $this->setExpectedException( 'RuntimeException' ); + StoreFactory::getStore( 'foo' ); + } + + /** + * smwfGetStore is deprecated but due to its dependency do a quick check here + * + * FIXME Delete this test in 1.11 + */ + public function testSmwfGetStore() { + $store = smwfGetStore(); + + $this->assertInstanceOf( 'SMWStore', $store ); + $this->assertInstanceOf( 'SMW\Store', $store ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/StoreTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/StoreTest.php new file mode 100644 index 00000000..37cd0ac9 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/StoreTest.php @@ -0,0 +1,250 @@ +<?php + +namespace SMW\Test; + +use SMW\Tests\MwDBaseUnitTestCase; + +use SMW\StoreFactory; +use SMW\DIProperty; +use SMW\DIWikiPage; + +use Title; +use SMWQueryProcessor; +use SMWRequestOptions; + +/** + * Tests for the SMWStore class. + * + * @since 1.8 + * + * @ingroup Test + * + * @group SMW + * @group SMWStore + * @group SMWExtension + * @group Database + * + * @author Nischay Nahata + */ +class StoreTest extends MwDBaseUnitTestCase { + +///// Reading methods ///// + + public function getSemanticDataProvider() { + return array( + array( Title::newMainPage()->getFullText() ), + #add more pages here, make sure they exist + #array( Test ), + ); + } + + /** + * @dataProvider getSemanticDataProvider + */ + public function testGetSemanticData( $titleText ,$filter = false) { + $title = Title::newFromText( $titleText ); + $subject = DIWikiPage::newFromTitle( $title ); + $store = StoreFactory::getStore(); + + $this->assertInstanceOf( + '\SMW\SemanticData', + $store->getSemanticData( $subject, $filter ), + "Result should be instance of SMWSemanticData." + ); + } + + public function getPropertyValuesDataProvider() { + return array( + array( Title::newMainPage()->getFullText(), new DIProperty('_MDAT') ), + array( Title::newMainPage()->getFullText(), DIProperty::newFromUserLabel('Age') ), + #add more pages and properties here, make sure they exist + #array( Test, Property ), + ); + } + + /** + * @dataProvider getPropertyValuesDataProvider + */ + public function testGetPropertyValues( $titleText, DIProperty $property, $requestOptions = null ) { + $title = Title::newFromText( $titleText ); + $subject = DIWikiPage::newFromTitle( $title ); + $store = StoreFactory::getStore(); + $result = $store->getPropertyValues( $subject, $property, $requestOptions ); + + $this->assertTrue( is_array( $result ) ); + + foreach( $result as $di ) { + $this->assertInstanceOf( + '\SMWDataItem', + $di, + "Result should be instance of SMWDataItem." + ); + } + } + + public function getPropertySubjectsDataProvider() { + return array( + array( new DIProperty('_MDAT'), null ), + #add more properties and values (SMWDataItem) here, make sure they exist + #array( Property, value ), + ); + } + + /** + * @dataProvider getPropertySubjectsDataProvider + */ + public function testGetPropertySubjects( DIProperty $property, $value, $requestOptions = null ) { + $store = StoreFactory::getStore(); + $result = $store->getPropertySubjects( $property, $value, $requestOptions ); + + $this->assertTrue( is_array( $result ) ); + + foreach( $result as $page ) { + $this->assertInstanceOf( + '\SMW\DIWikiPage', + $page, + "Result should be instance of DIWikiPage." + ); + } + } + + public function getPropertiesDataProvider() { + return array( + array( Title::newMainPage()->getFullText() ), + #add more pages here, make sure they exist + #array( Test ), + ); + } + + /** + * @dataProvider getPropertiesDataProvider + */ + public function testGetProperties( $titleText, $requestOptions = null ) { + $title = Title::newFromText( $titleText ); + $subject = DIWikiPage::newFromTitle( $title ); + $store = StoreFactory::getStore(); + $result = $store->getProperties( $subject, $requestOptions ); + + $this->assertTrue( is_array( $result ) ); + + foreach( $result as $property ) { + $this->assertInstanceOf( + '\SMW\DIProperty', + $property, + "Result should be instance of DIProperty." + ); + } + } + +///// Query answering ///// + + public function getQueryResultDataProvider() { + return array( + array( '[[Modification date::+]]|?Modification date|sort=Modification date|order=desc' ), + ); + } + + /** + * @dataProvider getQueryResultDataProvider + */ + public function testGetQueryResult( $query ) { + // TODO: this prevents doing [[Category:Foo||bar||baz]], must document. + // TODO: for some reason PHPUnit is failing here. Line in SQLStore2Queries with comment "This test printed output:" +// $rawParams = explode( '|', $query ); +// +// list( $queryString, $parameters, $printouts ) = SMWQueryProcessor::getComponentsFromFunctionParams( $rawParams, false ); +// SMWQueryProcessor::addThisPrintout( $printouts, $parameters ); +// $parameters = SMWQueryProcessor::getProcessedParams( $parameters, $printouts ); +// $smwQuery = SMWQueryProcessor::createQuery( $queryString, $parameters, SMWQueryProcessor::SPECIAL_PAGE, '', $printouts ); +// $store = \SMW\StoreFactory::getStore(); +// $queryResult = $store->getQueryResult( $smwQuery ); +// +// $this->assertInstanceOf( +// '\SMWQueryResult', +// $queryResult, +// "Result should be instance of SMWQueryResult." +// ); + + $this->assertTrue( true ); + } + +///// Special page functions ///// + + public function testGetPropertiesSpecial() { + // Really bailing out here and making the test database dependant!! + + // This test fails on mysql http://bugs.mysql.com/bug.php?id=10327 + if( $GLOBALS['wgDBtype'] == 'mysql' ) { + $this->assertTrue( true ); + return; + } + + $store = StoreFactory::getStore(); + $result = $store->getPropertiesSpecial( new SMWRequestOptions() ); + + $this->assertInstanceOf( '\SMW\ResultCollector', $result ); + foreach( $result->getResults() as $row ) { + $this->assertEquals( 2, sizeof( $row ) ); + + $this->assertInstanceOf( + '\SMW\DIProperty', + $row[0], + "Result should be instance of DIProperty." + ); + } + } + + public function testGetUnusedPropertiesSpecial() { + $store = StoreFactory::getStore(); + $result = $store->getUnusedPropertiesSpecial( new SMWRequestOptions() ); + + $this->assertInstanceOf( '\SMW\ResultCollector', $result ); + foreach( $result->getResults() as $row ) { + $this->assertInstanceOf( + '\SMW\DIProperty', + $row, + "Result should be instance of DIProperty." + ); + } + } + + public function testGetWantedPropertiesSpecial() { + $store = StoreFactory::getStore(); + $result = $store->getWantedPropertiesSpecial( new SMWRequestOptions() ); + + $this->assertInstanceOf( '\SMW\ResultCollector', $result ); + foreach( $result->getResults() as $row ) { + $this->assertInstanceOf( + '\SMW\DIProperty', + $row[0], + "Result should be instance of DIProperty." + ); + } + } + + public function testGetStatistics() { + $store = StoreFactory::getStore(); + $result = $store->getStatistics(); + + $this->assertTrue( is_array( $result ) ); + $this->assertArrayHasKey( 'PROPUSES', $result ); + $this->assertArrayHasKey( 'USEDPROPS', $result ); + $this->assertArrayHasKey( 'DECLPROPS', $result ); + } + + public function testSetGetDatabase() { + + $store = StoreFactory::getStore(); + + if ( !( $store instanceof \SMWSQLStore3 ) ) { + $this->markTestSkipped( 'Test is only available for SMWSQLStore3' ); + } + + $database = $store->getDatabase(); + + $this->assertInstanceOf( '\SMW\MediaWiki\Database', $database ); + $this->assertTrue( $database === $store->setDatabase( $database )->getDatabase() ); + + } + +}
\ No newline at end of file diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/DIHandlerWikiPageTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/DIHandlerWikiPageTest.php new file mode 100644 index 00000000..ec59e935 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/DIHandlerWikiPageTest.php @@ -0,0 +1,133 @@ +<?php + +namespace SMW\Test; + +use SMW\InvalidPredefinedPropertyException; +use SMW\StoreFactory; + +use SMWDIHandlerWikiPage; +use SMWDIProperty; + +/** + * Tests for the SMWDIHandlerWikiPage class + * + * @since 1.9 + * + * @file + * @ingroup Test + * + * @licence GNU GPL v2+ + * @author mwjames + */ + +/** + * Tests for the SMWDIHandlerWikiPage class + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class DIHandlerWikiPageTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string + */ + public function getClass() { + return 'SMWDIHandlerWikiPage'; + } + + /** + * Helper method that returns a SMWDIHandlerWikiPage object + * + * @since 1.9 + * + * @return SMWDIHandlerWikiPage + */ + private function getInstance() { + return new SMWDIHandlerWikiPage( StoreFactory::getStore( 'SMWSQLStore3' ) ); + } + + /** + * @test SMWDIHandlerWikiPage::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->getInstance() ); + } + + /** + * @test SMWDIHandlerWikiPage::dataItemFromDBKeys + * + * @since 1.9 + * + * @throws SMWDataItemException + */ + public function testDataItemFromDBKeysException() { + + $this->setExpectedException( 'SMWDataItemException' ); + + $instance = $this->getInstance(); + $result = $instance->dataItemFromDBKeys( array() ); + + $this->assertInstanceOf( 'SMWDIWikiPage', $result ); + + } + + /** + * @test SMWDIHandlerWikiPage::dataItemFromDBKeys + * @dataProvider getDBKeys + * + * @see bug 48711 + * + * @since 1.9 + * + * @param $dbKeys + * @param $expected + * + * @throws InvalidPredefinedPropertyException + */ + public function testDataItemFromDBKeys( $dbKeys, $expected ) { + + $instance = $this->getInstance(); + + try { + $result = $instance->dataItemFromDBKeys( $dbKeys ); + $this->assertInstanceOf( $expected, $result ); + return; + } catch ( InvalidPredefinedPropertyException $e ) { + $this->assertEquals( $expected, 'InvalidPredefinedPropertyException' ); + return; + } + + $this->fail( 'An expected exception has not been raised.' ); + } + + /** + * Provides dbKeys sample + * + * @return array + */ + public function getDBKeys() { + return array( + + // #0 SMW_NS_PROPERTY, user defined property + array( + array( 'Foo', SMW_NS_PROPERTY, 'bar', '', '' ), 'SMWDIWikiPage' + ), + + // #1 SMW_NS_PROPERTY, pre-defined property + array( + array( '_Foo', SMW_NS_PROPERTY, 'bar', '', '' ), 'SMWDIWikiPage' + ), + + // #2 SMW_NS_PROPERTY, pre-defined property (see bug 48711) + array( + array( '_Foo', SMW_NS_PROPERTY, '', '', '' ), 'InvalidPredefinedPropertyException' + ), + ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/PropertiesCollectorTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/PropertiesCollectorTest.php new file mode 100644 index 00000000..4364e29f --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/PropertiesCollectorTest.php @@ -0,0 +1,247 @@ +<?php + +namespace SMW\Test\SQLStore; + +use SMW\SQLStore\PropertiesCollector; + +use SMW\Test\SemanticMediaWikiTestCase; + +use SMW\MessageFormatter; +use SMW\StoreFactory; +use SMW\DIProperty; +use SMW\Settings; + +use SMWStringCondition; +use SMWRequestOptions; + +use FakeResultWrapper; + +/** + * @covers \SMW\SQLStore\PropertiesCollector + * + * @ingroup SQLStoreTest + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class PropertiesCollectorTest extends SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\SQLStore\PropertiesCollector'; + } + + /** + * @since 1.9 + * + * @return Database + */ + private function getMockDBConnection( $smwTitle = 'Foo', $smwId, $usageCount = 1 ) { + + $result = array( + 'smw_title' => $smwTitle, + 'smw_id' => $smwId, + 'p_id' => (string)$smwId, // PropertyStatisticsTable assert ctype_digit + 'usage_count' => (string)$usageCount // PropertyStatisticsTable assert ctype_digit + ); + + $resultWrapper = new FakeResultWrapper( array( (object)$result ) ); + + $databaseBase = $this->getMockBuilder( '\DatabaseBase' ) + ->disableOriginalConstructor() + ->setMethods( array( 'select' ) ) + ->getMockForAbstractClass(); + + $databaseBase->expects( $this->any() ) + ->method( 'select' ) + ->will( $this->returnValue( $resultWrapper ) ); + + return $databaseBase; + } + + /** + * @since 1.9 + * + * @return PropertiesCollector + */ + private function newInstance( $smwTitle = 'Foo', $usageCount = 1, $cacheEnabled = false ) { + + $id = 9999; + + $row = new \stdClass; + $row->p_id = (string)$id; // PropertyStatisticsTable assert ctype_digit + $row->usage_count = (string)$usageCount; // PropertyStatisticsTable assert ctype_digit + + $idTable = $this->getMockBuilder( '\stdClass' ) + ->setMethods( array( 'getIdTable' ) ) + ->getMock(); + + $idTable->expects( $this->any() ) + ->method( 'getIdTable' ) + ->will( $this->returnValue( 'foo' ) ); + + $database = $this->getMockBuilder( '\SMW\MediaWiki\Database' ) + ->disableOriginalConstructor() + ->getMock(); + + $database->expects( $this->any() ) + ->method( 'select' ) + ->will( $this->returnValue( array( $row ) ) ); + + $store = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->setMethods( array( 'getDatabase', 'getObjectIds' ) ) + ->getMock(); + + $store->expects( $this->any() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $store->expects( $this->any() ) + ->method( 'getObjectIds' ) + ->will( $this->returnValue( $idTable ) ); + + $connection = $this->getMockDBConnection( $smwTitle, $id, $usageCount ); + + $settings = Settings::newFromArray( array( + 'smwgCacheType' => 'hash', + 'smwgPropertiesCache' => $cacheEnabled, + 'smwgPropertiesCacheExpiry' => 360, + ) ); + + return new PropertiesCollector( $store, $connection, $settings ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testGetResults() { + + $property = $this->newRandomString(); + $count = rand(); + $expected = array( new DIProperty( $property ), $count ); + + $instance = $this->newInstance( $property, $count ); + $requestOptions = new SMWRequestOptions(); + $requestOptions->limit = 1; + $requestOptions->addStringCondition( $property, SMWStringCondition::STRCOND_MID ); + + $instance->setRequestOptions( $requestOptions ); + + $this->assertEquals( array( $expected ), $instance->getResults() ); + $this->assertEquals( 1, $instance->getCount() ); + + } + + /** + * @dataProvider exceptionDataProvider + * + * InvalidPropertyException is thrown but caught and is retuned as a + * SMWDIError object instead + * + * @since 1.9 + */ + public function testInvalidPropertyException( $property ) { + + $instance = $this->newInstance( $property ); + $results = $instance->getResults(); + + $this->assertInternalType( 'array', $results ); + $this->assertEquals( 1, $instance->getCount() ); + $this->assertInstanceOf( 'SMWDIError', $results[0][0] ); + $this->assertContains( + $property, + MessageFormatter::newFromArray( $this->getLanguage(), array( $results[0][0]->getErrors() ) )->getHtml() + ); + + } + + /** + * @dataProvider getCacheNonCacheDataProvider + * + * @since 1.9 + */ + public function testCacheNoCache( array $test, array $expected, array $info ) { + + // Sample A + $instance = $this->newInstance( + $test['A']['property'], + $test['A']['count'], + $test['cacheEnabled'] + ); + + $this->assertEquals( $expected['A'], $instance->getResults(), $info['msg'] ); + + // Sample B + $instance = $this->newInstance( + $test['B']['property'], + $test['B']['count'], + $test['cacheEnabled'] + ); + + $this->assertEquals( $expected['B'], $instance->getResults(), $info['msg'] ); + $this->assertEquals( $test['cacheEnabled'], $instance->isCached() ); + } + + /** + * @return array + */ + public function exceptionDataProvider() { + return array( array( '-Lala' ), array( '_Lila' ) ); + } + + /** + * @return array + */ + public function getCacheNonCacheDataProvider() { + $propertyA = $this->newRandomString(); + $propertyB = $this->newRandomString(); + $countA = rand(); + $countB = rand(); + + return array( + array( + + // #0 Cached + array( + 'cacheEnabled' => true, + 'A' => array( 'property' => $propertyA, 'count' => $countA ), + 'B' => array( 'property' => $propertyB, 'count' => $countB ), + ), + array( + 'A' => array( array( new DIProperty( $propertyA ), $countA ) ), + 'B' => array( array( new DIProperty( $propertyA ), $countA ) ) + ), + array( 'msg' => 'Failed asserting that A & B are identical for a cached result' ) + ), + array( + + // #1 Non-cached + array( + 'cacheEnabled' => false, + 'A' => array( 'property' => $propertyA, 'count' => $countA ), + 'B' => array( 'property' => $propertyB, 'count' => $countB ) + ), + array( + 'A' => array( array( new DIProperty( $propertyA ), $countA ) ), + 'B' => array( array( new DIProperty( $propertyB ), $countB ) ) + ), + array( 'msg' => 'Failed asserting that A & B are not identical for a non-cached result' ) + ) + ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/PropertyStatisticsTableTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/PropertyStatisticsTableTest.php new file mode 100644 index 00000000..37b22776 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/PropertyStatisticsTableTest.php @@ -0,0 +1,151 @@ +<?php + +namespace SMW\Test\SQLStore; + +use SMW\Tests\MwDBaseUnitTestCase; + +use SMW\SQLStore\PropertyStatisticsTable; +use SMW\StoreFactory; + +/** + * @uses \SMW\SQLStore\PropertyStatisticsTable + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group Database + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class PropertyStatisticsTableTest extends MwDBaseUnitTestCase { + + protected $statsTable = null; + + /** + * On the Windows platform pow( 2 , 31 ) returns with + * "MWException: The value to add must be a positive integer" therefore + * return true if this test runs on Windows + * + * @return boolean + */ + private function isWinOS() { + return strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN'; + } + + public function testDeleteAll() { + + $statsTable = new PropertyStatisticsTable( + $this->getStore()->getDatabase(), + \SMWSQLStore3::PROPERTY_STATISTICS_TABLE + ); + + $this->assertTrue( $statsTable->deleteAll() !== false ); + $this->assertTrue( $statsTable->deleteAll() !== false ); + + $statsTable->insertUsageCount( 1, 1 ); + + $this->assertTrue( $statsTable->deleteAll() !== false ); + + $this->assertTrue( $statsTable->getUsageCounts( array( 1, 2 ) ) === array() ); + } + + public function usageCountProvider() { + $usageCounts = array(); + + $usageCounts[] = array( 1, 0 ); + $usageCounts[] = array( 2, 1 ); + + for ( $propId = 3; $propId <= 42; $propId++ ) { + $usageCounts[] = array( $propId, mt_rand( 0, 100000 ) ); + } + + $usageCounts[] = array( 9001, $this->isWinOS() ? pow( 2 , 30 ) : pow( 2 , 31 ) ); + + return $usageCounts; + } + + /** + * @return \SMW\Store\PropertyStatisticsStore + */ + protected function getTable() { + if ( $this->statsTable === null ) { + + $this->statsTable = new PropertyStatisticsTable( + $this->getStore()->getDatabase(), + \SMWSQLStore3::PROPERTY_STATISTICS_TABLE + ); + + $this->assertTrue( $this->statsTable->deleteAll() !== false ); + } + + return $this->statsTable; + } + + /** + * @dataProvider usageCountProvider + * + * @param int $propId + * @param int $usageCount + */ + public function testInsertUsageCount( $propId, $usageCount ) { + + $table = $this->getTable(); + + $this->assertTrue( $table->insertUsageCount( $propId, $usageCount ) ); + + $usageCounts = $table->getUsageCounts( array( $propId ) ); + + $this->assertArrayHasKey( $propId, $usageCounts ); + $this->assertEquals( $usageCount, $usageCounts[$propId] ); + + $change = mt_rand( max( -100, -$usageCount ), 100 ); + + $this->assertTrue( $table->addToUsageCount( $propId, $change ) !== false ); + + $usageCounts = $table->getUsageCounts( array( $propId ) ); + + $this->assertArrayHasKey( $propId, $usageCounts ); + $this->assertEquals( $usageCount + $change, $usageCounts[$propId], 'Testing addToUsageCount with ' . $change ); + } + + public function testAddToUsageCounts() { + + $statsTable = new PropertyStatisticsTable( + $this->getStore()->getDatabase(), + \SMWSQLStore3::PROPERTY_STATISTICS_TABLE + ); + + $this->assertTrue( $statsTable->deleteAll() !== false ); + + $counts = array( + 1 => 42, + 2 => 0, + 9001 => 9001, + 9002 => $this->isWinOS() ? pow( 2 , 30 ) : pow( 2 , 31 ), + 9003 => 1, + ); + + foreach ( $counts as $propId => $count ) { + $this->assertTrue( $statsTable->insertUsageCount( $propId, $count ) !== false ); + } + + $additions = array( + 2 => 42, + 9001 => -9000, + 9003 => 0, + ); + + $this->assertTrue( $statsTable->addToUsageCounts( $additions ) !== false ); + + foreach ( $additions as $propId => $addition ) { + $counts[$propId] += $addition; + } + + $this->assertEquals( $counts, $statsTable->getUsageCounts( array_keys( $counts ) ) ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/PropertyTableDefinitionBuilderTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/PropertyTableDefinitionBuilderTest.php new file mode 100644 index 00000000..79879347 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/PropertyTableDefinitionBuilderTest.php @@ -0,0 +1,127 @@ +<?php + +namespace SMW\Test\SQLStore; + +use SMW\SQLStore\PropertyTableDefinitionBuilder; + +use SMWDataItem as DataItem; + +/** + * @covers \SMW\SQLStore\PropertyTableDefinitionBuilder + * + * @ingroup SQLStoreTest + * + * @group SMW + * @group SMWExtension + * @group StoreTest + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class PropertyTableDefinitionBuilderTest extends \PHPUnit_Framework_TestCase { + + protected $hooks = array(); + + protected function setUp() { + parent::setUp(); + + if ( isset( $GLOBALS['wgHooks']['SMW::SQLStore::updatePropertyTableDefinitions'] ) ) { + $this->hooks = $GLOBALS['wgHooks']['SMW::SQLStore::updatePropertyTableDefinitions']; + $GLOBALS['wgHooks']['SMW::SQLStore::updatePropertyTableDefinitions'] = array(); + } + } + + protected function tearDown() { + + if ( $this->hooks !== array() ) { + $GLOBALS['wgHooks']['SMW::SQLStore::updatePropertyTableDefinitions'] = $this->hooks; + } + + parent::tearDown(); + } + + public function getClass() { + return '\SMW\SQLStore\PropertyTableDefinitionBuilder'; + } + + /** + * @return PropertyTableDefinitionBuilder + */ + private function acquireInstance( $dataItems = array(), $specials = array(), $fixed = array() ) { + return new PropertyTableDefinitionBuilder( $dataItems, $specials, $fixed ); + } + + public function testCanConstruct() { + $this->assertInstanceOf( $this->getClass(), $this->acquireInstance() ); + } + + public function testDataItemTypes() { + + $parameters = array( DataItem::TYPE_NUMBER => 'smw_di_number' ); + + $instance = $this->acquireInstance( $parameters ); + $instance->runBuilder(); + + $definition = $instance->getDefinition( DataItem::TYPE_NUMBER, 'smw_di_number' ); + + $expected = array( + 'smw_di_number' => $definition + ); + + $this->assertEquals( $expected, $instance->getTableDefinitions() ); + } + + public function testFixedProperties() { + + $propertyKey = 'Foo'; + $parameters = array( $propertyKey => DataItem::TYPE_NUMBER ); + + $instance = $this->acquireInstance( array(), array(), $parameters ); + $instance->runBuilder(); + + $tableName = $instance->getTablePrefix() . '_' . md5( $propertyKey ); + $definition = $instance->getDefinition( DataItem::TYPE_NUMBER, $tableName, $propertyKey ); + + $expected = array( + 'definition' => array( $tableName => $definition ), + 'tableId' => array( $propertyKey => $tableName, '_SKEY' => null ) + ); + + $this->assertEquals( $expected['definition'], $instance->getTableDefinitions() ); + $this->assertEquals( $expected['tableId'], $instance->getTableIds() ); + } + + public function testSpecialProperties() { + + $propertyKey = '_MDAT'; + $parameters = array( $propertyKey ); + + $instance = $this->acquireInstance( array(), $parameters, array() ); + $instance->runBuilder(); + + $tableName = $instance->getTablePrefix() . strtolower( $propertyKey ); + $definition = $instance->getDefinition( DataItem::TYPE_TIME, $tableName, $propertyKey ); + $expected = array( $tableName => $definition ); + + $this->assertEquals( $expected, $instance->getTableDefinitions() ); + } + + public function testRedirects() { + + $propertyKey = '_REDI'; + $parameters = array( $propertyKey ); + + $instance = $this->acquireInstance( array(), $parameters, array() ); + $instance->runBuilder(); + + $tableName = $instance->getTablePrefix() . strtolower( $propertyKey ); + $definition = $instance->getDefinition( DataItem::TYPE_WIKIPAGE, $tableName, $propertyKey ); + $expected = array( $tableName => $definition ); + $tableDefinitions = $instance->getTableDefinitions(); + + $this->assertFalse( $tableDefinitions[$tableName]->usesIdSubject() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/SQLStoreSmwIdsTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/SQLStoreSmwIdsTest.php new file mode 100644 index 00000000..f20ab7a2 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/SQLStoreSmwIdsTest.php @@ -0,0 +1,202 @@ +<?php + +namespace SMW\Tests\SQLStore; + +use SMW\Tests\Util\Mock\MockDBConnectionProvider; +use SMW\MediaWiki\Database; + +use SMW\DIProperty; +use SMWSql3SmwIds; + +/** + * @covers \SMWSql3SmwIds + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * @group SQLStore + * @group MockTest + * + * @license GNU GPL v2+ + * @since 1.9.1 + * + * @author mwjames + */ +class SQLStoreSmwIdsTest extends \PHPUnit_Framework_TestCase { + + public function getClass() { + return '\SMWSql3SmwIds'; + } + + public function testCanConstruct() { + + $store = $this->getMockBuilder( 'SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertInstanceOf( $this->getClass(), new SMWSql3SmwIds( $store ) ); + } + + /** + * @depends testCanConstruct + */ + public function testGetPropertyId() { + + $selectRow = new \stdClass; + $selectRow->smw_id = 9999; + $selectRow->smw_sortkey = 'Foo'; + + $readConnection = new MockDBConnectionProvider(); + $mockDatabase = $readConnection->getMockDatabase(); + + $mockDatabase->expects( $this->once() ) + ->method( 'selectRow' ) + ->will( $this->returnValue( $selectRow ) ); + + $database = new Database( $readConnection, new MockDBConnectionProvider ); + + $store = $this->getMockBuilder( 'SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $store->expects( $this->once() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $instance = new SMWSql3SmwIds( $store ); + + $result = $instance->getSMWPropertyID( new DIProperty( 'Foo' ) ); + + $this->assertEquals( 9999, $result ); + } + + /** + * @dataProvider pageIdandSortProvider + */ + public function testGetSMWPageIDandSort( $parameters ) { + + $selectRow = new \stdClass; + $selectRow->smw_id = 9999; + $selectRow->smw_sortkey = 'Foo'; + $selectRow->smw_proptable_hash = serialize( 'Foo' ); + + $readConnection = new MockDBConnectionProvider(); + $mockDatabase = $readConnection->getMockDatabase(); + + $mockDatabase->expects( $this->once() ) + ->method( 'selectRow' ) + ->will( $this->returnValue( $selectRow ) ); + + $database = new Database( $readConnection, new MockDBConnectionProvider ); + + $store = $this->getMockBuilder( 'SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $store->expects( $this->once() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $instance = new SMWSql3SmwIds( $store ); + + $sortkey = $parameters['sortkey']; + + $result = $instance->getSMWPageIDandSort( + $parameters['title'], + $parameters['namespace'], + $parameters['iw'], + $parameters['subobjectName'], + $sortkey, // pass-by-reference + $parameters['canonical'], + $parameters['fetchHashes'] + ); + + $this->assertEquals( 9999, $result ); + } + + /** + * @dataProvider pageIdandSortProvider + */ + public function testMakeSMWPageID( $parameters ) { + + $selectRow = new \stdClass; + $selectRow->smw_id = 0; + $selectRow->o_id = 0; + $selectRow->smw_sortkey = 'Foo'; + $selectRow->smw_proptable_hash = serialize( 'Foo' ); + + $readConnection = new MockDBConnectionProvider(); + $mockReadDatabase = $readConnection->getMockDatabase(); + + $mockReadDatabase->expects( $this->any() ) + ->method( 'selectRow' ) + ->will( $this->returnValue( $selectRow ) ); + + $writeConnection = new MockDBConnectionProvider(); + $mockWriteDatabase = $writeConnection->getMockDatabase(); + + $mockWriteDatabase->expects( $this->once() ) + ->method( 'insertId' ) + ->will( $this->returnValue( 9999 ) ); + + $database = new Database( $readConnection, $writeConnection ); + + $store = $this->getMockBuilder( 'SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $store->expects( $this->any() ) + ->method( 'getDatabase' ) + ->will( $this->returnValue( $database ) ); + + $instance = new SMWSql3SmwIds( $store ); + + $sortkey = $parameters['sortkey']; + + $result = $instance->makeSMWPageID( + $parameters['title'], + $parameters['namespace'], + $parameters['iw'], + $parameters['subobjectName'], + $sortkey, + $parameters['canonical'], + $parameters['fetchHashes'] + ); + + $this->assertEquals( 9999, $result ); + } + + public function pageIdandSortProvider() { + + $provider[] = array( 'Foo', NS_MAIN, '' , '', 'FOO', false, false ); + $provider[] = array( 'Foo', NS_MAIN, '' , '', 'FOO', true, false ); + $provider[] = array( 'Foo', NS_MAIN, '' , '', 'FOO', true, true ); + $provider[] = array( 'Foo', NS_MAIN, 'quy' , '', 'FOO', false, false ); + $provider[] = array( 'Foo', NS_MAIN, 'quy' , 'xwoo', 'FOO', false, false ); + + $provider[] = array( 'pro', SMW_NS_PROPERTY, '' , '', 'PRO', false, false ); + $provider[] = array( 'pro', SMW_NS_PROPERTY, '' , '', 'PRO', true, false ); + $provider[] = array( 'pro', SMW_NS_PROPERTY, '' , '', 'PRO', true, true ); + + return $this->createAssociativeArrayFromProviderDefinition( $provider ); + } + + private function createAssociativeArrayFromProviderDefinition( $definitions ) { + + foreach ( $definitions as $map ) { + $provider[] = array( array( + 'title' => $map[0], + 'namespace' => $map[1], + 'iw' => $map[2], + 'subobjectName' => $map[3], + 'sortkey' => $map[4], + 'canonical' => $map[5], + 'fetchHashes' => $map[6] + ) ); + } + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/SQLStoreTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/SQLStoreTest.php new file mode 100644 index 00000000..18e2bb8a --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/SQLStoreTest.php @@ -0,0 +1,125 @@ +<?php + +namespace SMW\Test\SQLStore; + +use SMWSQLStore3; +use SMW\Settings; + +/** + * @covers \SMWSQLStore3 + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class SQLStoreTest extends \PHPUnit_Framework_TestCase { + + /** @var array */ + protected $defaultPropertyTableCount = 0; + + public function getClass() { + return '\SMWSQLStore3'; + } + + private function acquireInstance() { + $instance = new SMWSQLStore3(); + + $instance->setConfiguration( Settings::newFromArray( array( + 'smwgFixedProperties' => array(), + 'smwgPageSpecialProperties' => array() + ) ) ); + + $this->defaultPropertyTableCount = count( $instance->getPropertyTables() ); + $instance->clear(); + + return $instance; + } + + public function testCanConstruct() { + $instance = $this->acquireInstance(); + $this->assertInstanceOf( $this->getClass(), $instance ); + } + + /** + * @depends testCanConstruct + */ + public function testGetPropertyTables() { + + $instance = $this->acquireInstance(); + + $instance->setConfiguration( Settings::newFromArray( array( + 'smwgFixedProperties' => array(), + 'smwgPageSpecialProperties' => array() + ) ) ); + + $this->assertInternalType( 'array', $instance->getPropertyTables() ); + + foreach ( $instance->getPropertyTables() as $tid => $propTable ) { + $this->assertInstanceOf( '\SMW\SQLStore\TableDefinition', $propTable ); + } + } + + /** + * @depends testGetPropertyTables + */ + public function testPropertyTablesValidCustomizableProperty() { + + $instance = $this->acquireInstance(); + + $instance->setConfiguration( Settings::newFromArray( array( + 'smwgFixedProperties' => array(), + 'smwgPageSpecialProperties' => array( '_MDAT' ) + ) ) ); + + $this->assertCount( $this->defaultPropertyTableCount + 1, $instance->getPropertyTables() ); + $instance->clear(); + } + + /** + * @depends testGetPropertyTables + */ + public function testPropertyTablesWithInvalidCustomizableProperty() { + + $instance = $this->acquireInstance(); + + $instance->setConfiguration( Settings::newFromArray( array( + 'smwgFixedProperties' => array(), + 'smwgPageSpecialProperties' => array( '_MDAT', 'Foo' ) + ) ) ); + + $this->assertCount( $this->defaultPropertyTableCount + 1, $instance->getPropertyTables() ); + $instance->clear(); + } + + /** + * @depends testGetPropertyTables + */ + public function testPropertyTablesWithValidCustomizableProperties() { + + $instance = $this->acquireInstance(); + + $instance->setConfiguration( Settings::newFromArray( array( + 'smwgFixedProperties' => array(), + 'smwgPageSpecialProperties' => array( '_MDAT', '_MEDIA' ) + ) ) ); + + $this->assertCount( $this->defaultPropertyTableCount + 2, $instance->getPropertyTables() ); + $instance->clear(); + } + + public function testGetStatisticsTable() { + $this->assertInternalType( 'string', $this->acquireInstance()->getStatisticsTable() ); + } + + public function testGetObjectIds() { + $this->assertInternalType( 'object', $this->acquireInstance()->getObjectIds() ); + $this->assertInternalType( 'string', $this->acquireInstance()->getObjectIds()->getIdTable() ); + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/Sql3StubSemanticDataTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/Sql3StubSemanticDataTest.php new file mode 100644 index 00000000..9362ab56 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/Sql3StubSemanticDataTest.php @@ -0,0 +1,121 @@ +<?php + +namespace SMW\Tests\SQLStore; + +use SMW\StoreFactory; +use SMW\SemanticData; +use SMW\DIWikiPage; +use SMW\DIProperty; +use SMWDITime as DITime; +use SMWSql3StubSemanticData; + +use Title; + +/** + * @covers \SMWSql3StubSemanticData + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + * + * @license GNU GPL v2+ + * @since 1.9.0.2 + * + * @author mwjames + */ +class Sql3StubSemanticDataTest extends \PHPUnit_Framework_TestCase { + + /** @var Store */ + private $store; + + protected function setUp() { + $this->store = StoreFactory::getStore(); + } + + public function testCanConstruct() { + + $store = $this->getMockBuilder( '\SMWSQLStore3' ) + ->disableOriginalConstructor() + ->getMock(); + + $semanticData = $this->getMockBuilder( '\SMW\SemanticData' ) + ->disableOriginalConstructor() + ->getMock(); + + $semanticData->expects( $this->once() ) + ->method( 'getSubject' ) + ->will( $this->returnValue( DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ) ) ); + + $this->assertInstanceOf( + '\SMWSql3StubSemanticData', + SMWSql3StubSemanticData::newFromSemanticData( $semanticData, $store ) + ); + } + + public function testGetPropertyValues() { + + if ( !$this->store instanceOf \SMWSQLStore3 ) { + $this->markTestSkipped( "Requires a SMWSQLStore3 instance" ); + } + + $instance = SMWSql3StubSemanticData::newFromSemanticData( + new SemanticData( DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) ) ), + $this->store + ); + + $this->assertInstanceOf( + 'SMW\DIWikiPage', + $instance->getSubject() + ); + + $this->assertEmpty( + $instance->getPropertyValues( new DIProperty( 'unknownInverseProperty', true ) ) + ); + + $this->assertEmpty( + $instance->getPropertyValues( new DIProperty( 'unknownProperty' ) ) + ); + } + + /** + * @dataProvider removePropertyObjectProvider + */ + public function testRemovePropertyObjectValue( $title, $property, $dataItem ) { + + if ( !$this->store instanceOf \SMWSQLStore3 ) { + $this->markTestSkipped( "Requires a SMWSQLStore3 instance" ); + } + + $instance = SMWSql3StubSemanticData::newFromSemanticData( + new SemanticData( DIWikiPage::newFromTitle( $title ) ), + $this->store + ); + + $instance->addPropertyObjectValue( $property, $dataItem ); + $this->assertFalse( $instance->isEmpty() ); + + $instance->removePropertyObjectValue( $property, $dataItem ); + $this->assertTrue( $instance->isEmpty() ); + } + + /** + * @return array + */ + public function removePropertyObjectProvider() { + + $provider = array(); + + $title = Title::newFromText( 'Foo' ); + + // #0 + $provider[] = array( + $title, + new DIProperty( '_MDAT' ), + DITime::newFromTimestamp( 1272508903 ) + ); + + return $provider; + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/StatisticsCollectorTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/StatisticsCollectorTest.php new file mode 100644 index 00000000..1f0c258f --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/StatisticsCollectorTest.php @@ -0,0 +1,191 @@ +<?php + +namespace SMW\Test\SQLStore; + +use SMW\SQLStore\StatisticsCollector; +use SMW\StoreFactory; +use SMW\Settings; +use SMW\Store; + +use FakeResultWrapper; + +/** + * @covers \SMW\SQLStore\StatisticsCollector + * + * @ingroup SQLStoreTest + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class StatisticsCollectorTest extends \SMW\Test\SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\SQLStore\StatisticsCollector'; + } + + /** + * @since 1.9 + * + * @return StatisticsCollector + */ + private function newInstance( $count = 55, $cacheEnabled = false, $hash = 'foo' ) { + + $tableDefinition = $this->newMockBuilder()->newObject( 'SQLStoreTableDefinition', array( + 'isFixedPropertyTable' => true + ) ); + + $store = $this->newMockBuilder()->newObject( 'Store', array( + 'getPropertyTables' => array( 'Foo' => $tableDefinition ), + 'findTypeTableId' => 'Foo', + 'findPropertyTableID' => 'Foo' + ) ); + + $result = array( + 'count' => $count, + 'o_hash' => $hash + ); + + $resultWrapper = new FakeResultWrapper( array( (object)$result ) ); + $resultWrapper->count = $count; + + $connection = $this->newMockBuilder()->newObject( 'DatabaseBase', array( + 'select' => $resultWrapper, + 'selectRow' => $resultWrapper, + 'fetchObject' => $resultWrapper, + 'estimateRowCount' => $count + ) ); + + $settings = $this->newSettings( array( + 'smwgCacheType' => 'hash', + 'smwgStatisticsCache' => $cacheEnabled, + 'smwgStatisticsCacheExpiry' => 3600 + ) ); + + return new StatisticsCollector( $store, $connection, $settings ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @dataProvider getFunctionDataProvider + * + * @since 1.9 + */ + public function testFunctions( $function, $expectedType ) { + + $count = rand(); + $hash = 'Quxxey'; + $expectedCount = $expectedType === 'array' ? array( $hash => $count ) : $count; + + $instance = $this->newInstance( $count, false, $hash ); + + $result = call_user_func( array( &$instance, $function ) ); + + $this->assertInternalType( $expectedType, $result ); + $this->assertEquals( $expectedCount, $result ); + } + + /** + * @dataProvider getCollectorDataProvider + * + * @since 1.9 + */ + public function testResultsOnStore( $segment, $expectedType ) { + + $instance = $this->newInstance(); + $result = $instance->getResults(); + + $this->assertInternalType( $expectedType, $result[$segment] ); + } + + /** + * @dataProvider getCacheNonCacheDataProvider + * + * @since 1.9 + */ + public function testCachNoCache( array $test, array $expected ) { + + // Sample A + $instance = $this->newInstance( $test['A'], $test['cacheEnabled'] ); + $result = $instance->getResults(); + + $this->assertEquals( $expected['A'], $result['OWNPAGE'] ); + + // Sample B + $instance = $this->newInstance( $test['B'], $test['cacheEnabled'] ); + $result = $instance->getResults(); + $this->assertEquals( $expected['B'], $result['OWNPAGE'] ); + + $this->assertEquals( $test['cacheEnabled'], $instance->isCached() ); + + } + + /** + * @return array + */ + public function getFunctionDataProvider() { + return array( + array( 'getUsedPropertiesCount', 'integer' ), + array( 'getPropertyUsageCount', 'integer' ), + array( 'getDeclaredPropertiesCount', 'integer' ), + array( 'getSubobjectCount', 'integer' ), + array( 'getConceptCount', 'integer' ), + array( 'getQueryFormatsCount', 'array' ), + array( 'getQuerySize', 'integer' ), + array( 'getQueryCount', 'integer' ), + array( 'getPropertyPageCount', 'integer' ) + ); + } + + /** + * @return array + */ + public function getCollectorDataProvider() { + return array( + array( 'OWNPAGE', 'integer' ), + array( 'QUERY', 'integer' ), + array( 'QUERYSIZE', 'integer' ), + array( 'QUERYFORMATS', 'array' ), + array( 'CONCEPTS', 'integer' ), + array( 'SUBOBJECTS', 'integer' ), + array( 'DECLPROPS', 'integer' ), + array( 'USEDPROPS', 'integer' ), + array( 'PROPUSES', 'integer' ) + ); + } + + /** + * @return array + */ + public function getCacheNonCacheDataProvider() { + return array( + array( + + // #0 Invoke different A & B count but expect that + // A value is returned for both since cache is enabled + array( 'cacheEnabled' => true, 'A' => 1001, 'B' => 9001 ), + array( 'A' => 1001, 'B' => 1001 ) + ), + array( + + // #1 Invoke different A & B count and expect that since + // cache is disabled the original result is returned + array( 'cacheEnabled' => false, 'A' => 2001, 'B' => 9001 ), + array( 'A' => 2001, 'B' => 9001 ) + ) + ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/TableDefinitionTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/TableDefinitionTest.php new file mode 100644 index 00000000..b2977d11 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/TableDefinitionTest.php @@ -0,0 +1,124 @@ +<?php + +namespace SMW\Test\SQLStore; + +use SMW\SQLStore\TableDefinition; +use SMW\StoreFactory; + +use SMWDataItem; + +/** + * Test for the TableDefinition class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\SQLStore\TableDefinition + * + * @ingroup SQLStoreTest + * + * @group SMW + * @group SMWExtension + */ +class TableDefinitionTest extends \SMW\Test\SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\SQLStore\TableDefinition'; + } + + /** + * Helper method that returns a TableDefinition object + * + * @since 1.9 + * + * @return TableDefinition + */ + private function newInstance( $DIType = '' , $tableName = '' ) { + return new TableDefinition( $DIType, $tableName ); + } + + /** + * @test TableDefinition::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @test TableDefinition::getFields + * @test TableDefinition::getDiType + * @test TableDefinition::getName + * + * @since 1.9 + */ + public function testGetters() { + + $diType = SMWDataItem::TYPE_NUMBER; + $name = 'smw_di_number'; + + $instance = $this->newInstance( $diType, $name ); + + $this->assertInternalType( + 'array', + $instance->getFields( StoreFactory::getStore( 'SMWSQLStore3' ) ), + 'Asserts that getFields() returns an array' + ); + + $this->assertEquals( + $diType, + $instance->getDiType(), + 'Asserts that getDiType() returns the corret object' + ); + + $this->assertEquals( + $name, + $instance->getName(), + 'Asserts that getName() returns the corret object' + ); + + } + + /** + * @test TableDefinition::usesIdSubject + * @test TableDefinition::setUsesIdSubject + * + * @since 1.9 + */ + public function testIdSubject() { + + $instance = $this->newInstance(); + $instance->setUsesIdSubject( false ); + + $this->assertFalse( + $instance->usesIdSubject(), + 'Asserts that usesIdSubject() returns false' + ); + + } + + /** + * @test TableDefinition::getFixedProperty + * + * @since 1.9 + */ + public function testGetFixedProperty() { + + $this->setExpectedException( 'OutOfBoundsException' ); + $this->newInstance()->getFixedProperty(); + + } + +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/UnusedPropertiesCollectorTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/UnusedPropertiesCollectorTest.php new file mode 100644 index 00000000..4dd3a6af --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/UnusedPropertiesCollectorTest.php @@ -0,0 +1,182 @@ +<?php + +namespace SMW\Test\SQLStore; + +use SMW\SQLStore\UnusedPropertiesCollector; + +use SMW\MessageFormatter; +use SMW\StoreFactory; +use SMW\DIProperty; + +use SMWRequestOptions; + +use FakeResultWrapper; + +/** + * @covers \SMW\SQLStore\UnusedPropertiesCollector + * + * @ingroup SQLStoreTest + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class UnusedPropertiesCollectorTest extends \SMW\Test\SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\SQLStore\UnusedPropertiesCollector'; + } + + /** + * @since 1.9 + * + * @return UnusedPropertiesCollector + */ + private function newInstance( $smwTitle = 'Foo', $cacheEnabled = false ) { + + $mockStore = $this->newMockBuilder()->newObject( 'Store' ); + + $result = array( + 'smw_title' => $smwTitle, + ); + + $connection = $this->newMockBuilder()->newObject( 'DatabaseBase', array( + 'select' => new FakeResultWrapper( array( (object)$result ) ) + ) ); + + $settings = $this->newSettings( array( + 'smwgCacheType' => 'hash', + 'smwgUnusedPropertiesCache' => $cacheEnabled, + 'smwgUnusedPropertiesCacheExpiry' => 360, + ) ); + + return new UnusedPropertiesCollector( $mockStore, $connection, $settings ); + } + + /** + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @since 1.9 + */ + public function testGetResults() { + + $property = $this->newRandomString(); + $expected = array( new DIProperty( $property ) ); + + $instance = $this->newInstance( $property ); + $requestOptions = new SMWRequestOptions( $property, \SMWStringCondition::STRCOND_PRE ); + $requestOptions->limit = 1; + + $instance->setRequestOptions( $requestOptions ); + + $this->assertEquals( $expected, $instance->getResults() ); + $this->assertEquals( 1, $instance->getCount() ); + + } + + /** + * @dataProvider exceptionDataProvider + * + * InvalidPropertyException is thrown but caught and returning with a + * SMWDIError instead + * + * @since 1.9 + */ + public function testInvalidPropertyException( $property ) { + + $instance = $this->newInstance( $property ); + $results = $instance->getResults(); + + $this->assertInternalType( 'array', $results ); + $this->assertEquals( 1, $instance->getCount() ); + $this->assertInstanceOf( 'SMWDIError', $results[0] ); + $this->assertContains( + $property, + MessageFormatter::newFromArray( $this->getLanguage(), array( $results[0]->getErrors() ) )->getHtml() + ); + + } + + /** + * @dataProvider getCacheNonCacheDataProvider + * + * @since 1.9 + */ + public function testCacheNoCache( array $test, array $expected, array $info ) { + + // Sample A + $instance = $this->newInstance( + $test['A']['property'], + $test['cacheEnabled'] + ); + + $this->assertEquals( $expected['A'], $instance->getResults(), $info['msg'] ); + + // Sample B + $instance = $this->newInstance( + $test['B']['property'], + $test['cacheEnabled'] + ); + + $this->assertEquals( $expected['B'], $instance->getResults(), $info['msg'] ); + $this->assertEquals( $test['cacheEnabled'], $instance->isCached() ); + } + + /** + * @return array + */ + public function exceptionDataProvider() { + return array( array( '-Lala' ), array( '_Lila' ) ); + } + + /** + * @return array + */ + public function getCacheNonCacheDataProvider() { + $propertyA = $this->newRandomString(); + $propertyB = $this->newRandomString(); + + return array( + array( + + // #0 Cached + array( + 'cacheEnabled' => true, + 'A' => array( 'property' => $propertyA ), + 'B' => array( 'property' => $propertyB ), + ), + array( + 'A' => array( new DIProperty( $propertyA ) ), + 'B' => array( new DIProperty( $propertyA ) ) + ), + array( 'msg' => 'Failed asserting that A & B are identical for a cached result' ) + ), + array( + + // #1 Non-cached + array( + 'cacheEnabled' => false, + 'A' => array( 'property' => $propertyA ), + 'B' => array( 'property' => $propertyB ) + ), + array( + 'A' => array( new DIProperty( $propertyA ) ), + 'B' => array( new DIProperty( $propertyB ) ) + ), + array( 'msg' => 'Failed asserting that A & B are not identical for a non-cached result' ) + ) + ); + } +} diff --git a/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/WantedPropertiesCollectorTest.php b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/WantedPropertiesCollectorTest.php new file mode 100644 index 00000000..ed9e6db6 --- /dev/null +++ b/SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/WantedPropertiesCollectorTest.php @@ -0,0 +1,226 @@ +<?php + +namespace SMW\Test\SQLStore; + +use SMW\SQLStore\WantedPropertiesCollector; +use SMW\StoreFactory; +use SMW\DIProperty; +use SMW\Settings; + +use SMWRequestOptions; + +use FakeResultWrapper; + +/** + * @covers \SMW\SQLStore\WantedPropertiesCollector + * + * @ingroup SQLStoreTest + * + * @group SMW + * @group SMWExtension + * + * @licence GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ +class WantedPropertiesCollectorTest extends \SMW\Test\SemanticMediaWikiTestCase { + + /** + * @return string|false + */ + public function getClass() { + return '\SMW\SQLStore\WantedPropertiesCollector'; + } + + private function newInstance( $store = null, $property = 'Foo', $count = 1, $cacheEnabled = false ) { + + if ( $store === null ) { + $store = $this->newMockBuilder()->newObject( 'Store' ); + } + + $result = array( + 'count' => $count, + 'smw_title' => $property + ); + + $connection = $this->newMockBuilder()->newObject( 'DatabaseBase', array( + 'select' => new FakeResultWrapper( array( (object)$result ) ) + ) ); + + $settings = $this->newSettings( array( + 'smwgPDefaultType' => '_wpg', + 'smwgCacheType' => 'hash', + 'smwgWantedPropertiesCache' => $cacheEnabled, + 'smwgWantedPropertiesCacheExpiry' => 360, + ) ); + + return new WantedPropertiesCollector( $store, $connection, $settings ); + } + + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + public function testGetResultsOnSQLStore() { + + $store = StoreFactory::getStore( 'SMWSQLStore3' ); + + $count = rand(); + $property = $this->newRandomString(); + $expected = array( array( new DIProperty( $property ), $count ) ); + + $instance = $this->newInstance( $store, $property, $count ); + $instance->setRequestOptions( + new SMWRequestOptions( $property, \SMWStringCondition::STRCOND_PRE ) + ); + + $this->assertEquals( $expected, $instance->getResults() ); + $this->assertEquals( 1, $instance->getCount() ); + + } + + public function testIsFixedPropertyTableOnSQLMockStore() { + + $tableDefinition = $this->newMockBuilder()->newObject( 'SQLStoreTableDefinition', array( + 'isFixedPropertyTable' => true + ) ); + + $store = $this->newMockBuilder()->newObject( 'Store', array( + 'getPropertyTables' => array( 'Foo' => $tableDefinition ), + 'findTypeTableId' => 'Foo' + ) ); + + $result = $this->newInstance( $store )->runCollector(); + + $this->assertInternalType( + 'array', + $result, + 'Asserts that runCollector() returns an array' + ); + + $this->assertEmpty( + $result, + 'Asserts that runCollector() returns an empty array' + ); + + } + + /** + * @dataProvider getCacheNonCacheDataProvider + */ + public function testCacheNoCacheOnSQLStore( array $test, array $expected, array $info ) { + + $store = StoreFactory::getStore( 'SMWSQLStore3' ); + + // Sample A + $instance = $this->newInstance( + $store, + $test['A']['property'], + $test['A']['count'], + $test['cacheEnabled'] + ); + + $this->assertEquals( $expected['A'], $instance->getResults(), $info['msg'] ); + + // Sample B + $instance = $this->newInstance( + $store, + $test['B']['property'], + $test['B']['count'], + $test['cacheEnabled'] + ); + + $this->assertEquals( $expected['B'], $instance->getResults(), $info['msg'] ); + $this->assertEquals( $test['cacheEnabled'], $instance->isCached() ); + } + + public function getCacheNonCacheDataProvider() { + $propertyA = $this->newRandomString(); + $propertyB = $this->newRandomString(); + $countA = rand(); + $countB = rand(); + + return array( + array( + + // #0 Cached + array( + 'cacheEnabled' => true, + 'A' => array( 'property' => $propertyA, 'count' => $countA ), + 'B' => array( 'property' => $propertyB, 'count' => $countB ), + ), + array( + 'A' => array( array( new DIProperty( $propertyA ), $countA ) ), + 'B' => array( array( new DIProperty( $propertyA ), $countA ) ) + ), + array( 'msg' => 'Failed asserting that A & B are identical for a cached result' ) + ), + array( + + // #1 Non-cached + array( + 'cacheEnabled' => false, + 'A' => array( 'property' => $propertyA, 'count' => $countA ), + 'B' => array( 'property' => $propertyB, 'count' => $countB ) + ), + array( + 'A' => array( array( new DIProperty( $propertyA ), $countA ) ), + 'B' => array( array( new DIProperty( $propertyB ), $countB ) ) + ), + array( 'msg' => 'Failed asserting that A & B are not identical for a non-cached result' ) + ) + ); + } + + public function testUnknownPredefinedPropertyThrowsExceptionToReturnErrorDataItem() { + + $tableDefinition = $this->getMockBuilder( '\stdClass' ) + ->setMethods( array( 'isFixedPropertyTable', 'getName' ) ) + ->getMock(); + + $tableDefinition->expects( $this->once() ) + ->method( 'isFixedPropertyTable' ) + ->will( $this->returnValue( false ) ); + + $tableDefinition->expects( $this->once() ) + ->method( 'getName' ) + ->will( $this->returnValue( 'Bar' ) ); + + $store = $this->getMockBuilder( '\SMWSQLStore3' ) + ->setMethods( array( 'getPropertyTables', 'findTypeTableId' ) ) + ->getMock(); + + $store->expects( $this->once() ) + ->method( 'getPropertyTables' ) + ->will( $this->returnValue( array( 'Foo' => $tableDefinition ) ) ); + + $store->expects( $this->atLeastOnce() ) + ->method( 'findTypeTableId' ) + ->will( $this->returnValue( 'Foo' ) ); + + $row = new \stdClass(); + $row->smw_title = '_UnknownPredefinedProperty'; + $row->count = 0; + + $dbConnection = $this->getMockBuilder( '\DatabaseBase' ) + ->disableOriginalConstructor() + ->setMethods( array( 'select' ) ) + ->getMockForAbstractClass(); + + $dbConnection->expects( $this->once() ) + ->method( 'select' ) + ->will( $this->returnValue( array( $row ) ) ); + + $settings = Settings::newFromArray( array( + 'smwgPDefaultType' => 'Foo' + ) ); + + $instance = new WantedPropertiesCollector( $store, $dbConnection, $settings ); + $results = $instance->runCollector(); + + $this->assertInternalType( 'array', $results ); + $this->assertInstanceOf( 'SMWDIError', $results[0][0] ); + } + +} |