summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Legler <alex@a3li.li>2014-12-23 17:49:26 +0100
committerAlex Legler <alex@a3li.li>2014-12-23 17:49:26 +0100
commite352fff59842ca14fbfd81ee1c4a64297bb598c5 (patch)
tree153f268484aa5cc41cacf912bdce8c4847df222d /SemanticMediaWiki/tests/phpunit/includes
downloadextensions-e352fff59842ca14fbfd81ee1c4a64297bb598c5.tar.gz
extensions-e352fff59842ca14fbfd81ee1c4a64297bb598c5.tar.bz2
extensions-e352fff59842ca14fbfd81ee1c4a64297bb598c5.zip
Add initial set of additional extensions
Diffstat (limited to 'SemanticMediaWiki/tests/phpunit/includes')
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Annotator/CategoryPropertyAnnotatorTest.php318
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Annotator/ChainablePropertyAnnotatorTest.php121
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Annotator/NullPropertyAnnotatorTest.php54
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Annotator/PredefinedPropertyAnnotatorTest.php307
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Annotator/PropertyAnnotatorFactoryTest.php124
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Annotator/RedirectPropertyAnnotatorTest.php126
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Annotator/SortkeyPropertyAnnotatorTest.php109
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/ApplicationTest.php126
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Configuration/ConfigurationTest.php54
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/ContentParserTest.php330
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/CurlRequestTest.php58
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/DataTypeRegistryTest.php179
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/DataValueFactoryTest.php385
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/DefinesTest.php67
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxBuilderTest.php64
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxCacheTest.php493
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxMagicWordsTest.php199
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Factbox/FactboxTest.php498
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/FormatFactoryTest.php248
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/GlobalFunctionsTest.php150
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/HashIdGeneratorTest.php79
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/HighlighterTest.php118
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/InTextAnnotationParserTemplateTransclusionTest.php144
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/InTextAnnotationParserTest.php405
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/InfolinkTest.php90
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/ApiQueryResultFormatterTest.php345
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/ApiRequestParameterFormatterTest.php93
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/AskArgsTest.php260
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/AskTest.php104
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/BrowseBySubjectTest.php144
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/InfoTest.php152
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Api/QueryTest.php133
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/DatabaseTest.php207
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/DirectDBConnectionProviderTest.php55
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/EditInfoProviderTest.php223
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ArticleDeleteTest.php107
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ArticleFromTitleTest.php74
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ArticlePurgeTest.php185
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/BaseTemplateToolboxTest.php199
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/BeforeDisplayNoArticleTextTest.php75
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/BeforePageDisplayTest.php134
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ExtensionSchemaUpdatesTest.php48
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ExtensionTypesTest.php42
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/FileUploadTest.php91
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/GetPreferencesTest.php52
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/InternalParseBeforeLinksTest.php254
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/LinksUpdateConstructedTest.php82
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/NewRevisionFromEditCompleteTest.php210
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/OutputPageParserOutputTest.php347
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ParserAfterTidyTest.php267
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ResourceLoaderGetConfigVarsTest.php42
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/ResourceLoaderTestModulesTest.php50
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/SkinAfterContentTest.php259
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/SkinTemplateNavigationTest.php78
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/SpecialStatsAddExtraTest.php178
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/TitleIsAlwaysKnownTest.php72
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Hooks/TitleMoveCompleteTest.php95
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/DeleteSubjectJobTest.php221
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/JobFactoryTest.php52
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/RefreshJobTest.php182
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/UpdateDispatcherJobTest.php308
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/Jobs/UpdateJobTest.php175
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/LazyDBConnectionProviderTest.php68
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/MagicWordFinderTest.php122
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/PageCreatorTest.php51
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/PageInfoProviderTest.php326
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/RedirectTargetFinderTest.php53
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/TitleCreatorTest.php114
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/MediaWiki/TitleLookupTest.php223
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/NamespaceExaminerTest.php145
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/NamespaceManagerTest.php132
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/ParserDataTest.php239
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/ProfilerTest.php100
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/PropertyTypeDiffFinderTest.php180
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/RecurringEventsTest.php392
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Reporter/MessageReporterTestCase.php69
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Reporter/ObservableMessageReporterTest.php115
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/BadHttpDatabaseResponseExceptionTest.php53
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/BadHttpResponseMapperTest.php132
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/DatabaseConnectorExceptionTest.php126
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/DatabaseConnectorHttpRequestIntegrityTest.php199
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/FalseConditionTest.php43
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/FilterConditionTest.php55
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/SingletonConditionTest.php58
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/TrueConditionTest.php43
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/Condition/WhereConditionTest.php55
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/FederateResultListTest.php128
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/QueryConditionBuilderTest.php558
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/QueryEngineTest.php194
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/RawResultParserTest.php151
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/QueryEngine/ResultListConverterTest.php188
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/RedirectLookupTest.php215
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/SparqlDBConnectionProviderTest.php204
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/SparqlStoreTest.php140
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SPARQLStore/TurtleTriplesBuilderTest.php69
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SQLStore/SqlStoreWriterChangeTitleTest.php159
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SQLStore/SqlStoreWriterDataUpdateTest.php208
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SQLStore/SqlStoreWriterDeleteSubjectTest.php147
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SemanticDataTest.php491
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SettingsTest.php209
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SetupTest.php635
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SimpleDictionaryTest.php267
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Store/Maintenance/ConceptCacheRebuilderTest.php230
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Store/Maintenance/DataRebuilderTest.php297
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/Store/Maintenance/SimplePropertyStatisticsRebuilderTest.php117
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/StoreUpdaterTest.php202
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/SubobjectTest.php395
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/articlepages/ConceptPageTest.php55
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/articlepages/PropertyPageTest.php55
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/cache/CacheHandlerTest.php178
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/cache/CacheIdGeneratorTest.php101
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/cache/CacheableResultMapperTest.php81
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/context/EmptyContextTest.php59
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/context/ExtensionContextTest.php124
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/dataitems/DIConceptTest.php95
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/dataitems/DIPropertyTest.php92
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/dataitems/DIWikiPageTest.php53
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_BlobTest.php49
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_BoolTest.php64
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_GeoCoordTest.php49
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/dataitems/DI_NumberTest.php65
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/dataitems/DataItemTest.php144
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/dic/DependencyInjectorTest.php73
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/dic/NullDependencyContainerTest.php46
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/dic/SharedDependencyContainerTest.php216
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/dic/SimpleDependencyBuilderTest.php873
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/export/ExportSemanticDataTest.php314
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/export/SMWExpElementTest.php170
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/export/SMWExporterTest.php84
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/formatters/MessageFormatterTest.php283
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/formatters/ParameterFormatterFactoryTest.php73
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/formatters/ParserParameterFormatterTest.php335
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/formatters/TableFormatterTest.php362
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/parserhooks/AskParserFunctionTest.php323
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/parserhooks/ConceptParserFunctionTest.php211
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/parserhooks/DeclareParserFunctionTest.php46
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/parserhooks/DocumentationParserFunctionTest.php57
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/parserhooks/InfoParserFunctionTest.php57
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/parserhooks/ParserFunctionFactoryTest.php67
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/parserhooks/RecurringEventsParserFunctionTest.php475
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/parserhooks/SetParserFunctionTest.php176
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/parserhooks/ShowParserFunctionTest.php199
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/parserhooks/SubobjectParserFunctionTest.php397
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/query/QueryDescriptionTest.php270
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/query/QueryParserTest.php308
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/query/QueryProcessorTest.php62
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/query/QueryTest.php93
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/query/profiler/DescriptionProfileTest.php89
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/query/profiler/DurationProfileTest.php91
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/query/profiler/FormatProfileTest.php75
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/query/profiler/NullProfileTest.php65
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/querypages/PropertiesQueryPageTest.php324
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/querypages/QueryPageTest.php136
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/querypages/UnusedPropertiesQueryPageTest.php174
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/querypages/WantedPropertiesQueryPageTest.php148
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/queryprinters/AggregatablePrinterTest.php286
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/queryprinters/CategoryResultPrinterTest.php42
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/queryprinters/CsvResultPrinterTest.php209
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/queryprinters/DsvResultPrinterTest.php44
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/queryprinters/EmbeddedResultPrinterTest.php42
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/queryprinters/FeedResultPrinterTest.php109
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/queryprinters/JsonResultPrinterTest.php133
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/queryprinters/RawResultPrinterTest.php48
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/queryprinters/RdfResultPrinterTest.php42
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/queryprinters/ResultPrintersTest.php89
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/queryprinters/TableResultPrinterTest.php322
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/serializer/QueryResultSerializerTest.php181
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/serializer/SemanticDataDeserializerTest.php97
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/serializer/SemanticDataSerializerDeserializerRoundtripTest.php242
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/serializer/SemanticDataSerializerTest.php117
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/serializer/SerializerFactoryTest.php142
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/specials/SpecialConceptsTest.php94
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/specials/SpecialSMWAdminTest.php110
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/specials/SpecialsTest.php160
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/CacheableResultCollectorTest.php150
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/QueryOutputFormatterTest.php46
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/StoreFactoryTest.php98
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/StoreTest.php250
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/DIHandlerWikiPageTest.php133
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/PropertiesCollectorTest.php247
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/PropertyStatisticsTableTest.php151
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/PropertyTableDefinitionBuilderTest.php127
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/SQLStoreSmwIdsTest.php202
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/SQLStoreTest.php125
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/Sql3StubSemanticDataTest.php121
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/StatisticsCollectorTest.php191
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/TableDefinitionTest.php124
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/UnusedPropertiesCollectorTest.php182
-rw-r--r--SemanticMediaWiki/tests/phpunit/includes/storage/sqlstore/WantedPropertiesCollectorTest.php226
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, &#x108;io bonas dans l'&eacute;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( '&lt;Foo&gt;', $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] );
+ }
+
+}