[ 'mass–energy equivalence', 'physical law relating mass to energy', 'E = mc^2' ], 'Q2' => [ 'energy', 'measure for the ability of a system to do work', 'E' ], 'Q3' => [ 'speed of light', 'speed at which all massless particles and associated fields travel in vacuum', 'c' ], 'Q4' => [ 'mass', 'property of matter to resist changes of the state of motion and to attract other bodies', 'm' ] ]; public function getWikibaseConnectorWithExistingItems( EntityRevision $entityRevision, bool $storageExceptionOnQ3 = false, LoggerInterface $logger = null, EntityIdParser $parser = null ): MathWikibaseConnector { $revisionLookupMock = $this->createMock( EntityRevisionLookup::class ); $revisionLookupMock->method( 'getEntityRevision' )->willReturnCallback( static function ( EntityId $entityId ) use ( $entityRevision, $storageExceptionOnQ3 ) { if ( $storageExceptionOnQ3 && $entityId->getSerialization() === 'Q3' ) { throw new StorageException( 'Test Exception' ); } else { return $entityRevision; } } ); $revisionLookupMock->expects( self::atLeastOnce() ) ->method( 'getEntityRevision' ); $fallbackLabelDescriptionLookupFactoryMock = $this->createMock( FallbackLabelDescriptionLookupFactory::class ); $languageMock = $this->createMock( Language::class ); $languageFactoryMock = $this->createMock( LanguageFactory::class ); $languageFactoryMock->method( 'getLanguage' ) ->with( 'en' ) ->willReturn( $languageMock ); $languageNameUtilsMock = $this->createMock( LanguageNameUtils::class ); $languageNameUtilsMock->method( 'isValidCode' ) ->with( 'en' ) ->willReturn( true ); $fallbackLabelDescriptionLookupFactoryMock->method( 'newLabelDescriptionLookup' ) ->with( $languageMock ) ->willReturnCallback( [ $this, 'newLabelDescriptionLookup' ] ); return self::getWikibaseConnector( $languageFactoryMock, $languageNameUtilsMock, $fallbackLabelDescriptionLookupFactoryMock, $revisionLookupMock, $logger, $parser ); } public function getWikibaseConnector( LanguageFactory $languageFactory = null, LanguageNameUtils $languageNameUtils = null, FallbackLabelDescriptionLookupFactory $labelDescriptionLookupFactory = null, EntityRevisionLookup $entityRevisionLookupMock = null, LoggerInterface $logger = null, EntityIdParser $parser = null ): MathWikibaseConnector { $labelDescriptionLookupFactory = $labelDescriptionLookupFactory ?: $this->createMock( FallbackLabelDescriptionLookupFactory::class ); $entityRevisionLookup = $entityRevisionLookupMock ?: $this->createMock( EntityRevisionLookup::class ); $languageFactory = $languageFactory ?: $this->createMock( LanguageFactory::class ); if ( !$languageNameUtils ) { $languageNameUtils = $this->createMock( LanguageNameUtils::class ); $languageNameUtils->method( 'isValidCode' )->willReturn( true ); } $site = $this->createMock( Site::class ); $site->method( 'getGlobalId' )->willReturn( '' ); $site->method( 'getPageUrl' )->willReturn( self::EXAMPLE_URL ); $repoConnector = $this->createMock( RepoLinker::class ); $repoConnector->method( 'getEntityUrl' ) ->willReturnCallback( static function ( ItemId $itemId ) { return self::EXAMPLE_URL . 'wiki/Special:EntityPage/' . $itemId->getSerialization(); } ); $mathFormatter = $this->createMock( MathFormatter::class ); $mathFormatter->method( 'format' ) ->willReturnCallback( static function ( StringValue $value ) { return self::getExpectedMathML( $value->getValue() ); } ); return new MathWikibaseConnector( new ServiceOptions( MathWikibaseConnector::CONSTRUCTOR_OPTIONS, [ 'MathWikibasePropertyIdHasPart' => 'P1', 'MathWikibasePropertyIdDefiningFormula' => 'P2', 'MathWikibasePropertyIdQuantitySymbol' => 'P3', 'MathWikibasePropertyIdInDefiningFormula' => 'P4', 'MathWikibasePropertyIdSymbolRepresents' => 'P5' ] ), $repoConnector, $languageFactory, $languageNameUtils, $entityRevisionLookup, $labelDescriptionLookupFactory, $site, $parser ?: new BasicEntityIdParser(), $mathFormatter, $logger ?: new TestLogger() ); } public function setupMassEnergyEquivalenceItem( bool $hasPartMode ) { $partPropertyId = new NumericPropertyId( $hasPartMode ? 'P1' : 'P4' ); $symbolPropertyId = new NumericPropertyId( $hasPartMode ? 'P3' : 'P5' ); $items = []; $statements = []; foreach ( self::TEST_ITEMS as $key => $itemInfo ) { $itemId = new ItemId( $key ); $items[ $key ] = new Item( $itemId ); $siteLinkMock = $this->createMock( SiteLink::class ); $siteLinkMock->method( 'getSiteId' )->willReturn( '' ); $siteLinkMock->method( 'getPageName' )->willReturn( '' ); $items[ $key ]->addSiteLink( $siteLinkMock ); if ( $key === 'Q1' ) { continue; } $partSnak = new PropertyValueSnak( $partPropertyId, $hasPartMode ? new EntityIdValue( $items[ $key ]->getId() ) : new StringValue( $itemInfo[2] ) ); $partQualifier = new PropertyValueSnak( $symbolPropertyId, $hasPartMode ? new StringValue( $itemInfo[2] ) : new EntityIdValue( $items[ $key ]->getId() ) ); $statement = new Statement( $partSnak ); $statement->setQualifiers( new SnakList( [ $partQualifier ] ) ); $statements[] = $statement; } $mainFormulaValue = new StringValue( self::TEST_ITEMS[ 'Q1' ][2] ); $definingFormulaStatement = new Statement( new PropertyValueSnak( new NumericPropertyId( 'P2' ), $mainFormulaValue ) ); $statementList = new StatementList( ...$statements ); $statementList->addStatement( $definingFormulaStatement ); $items[ 'Q1' ]->setStatements( $statementList ); return $items[ 'Q1' ]; } public function newLabelDescriptionLookup(): FallbackLabelDescriptionLookup { $lookup = $this->createMock( FallbackLabelDescriptionLookup::class ); $lookup->method( 'getLabel' ) ->willReturnCallback( static function ( EntityId $entityId ) { if ( self::TEST_ITEMS[ $entityId->getSerialization() ] !== null ) { return new Term( 'en', self::TEST_ITEMS[ $entityId->getSerialization() ][0] ); } else { return null; } } ); $lookup->method( 'getDescription' ) ->willReturnCallback( static function ( EntityId $entityId ) { if ( self::TEST_ITEMS[ $entityId->getSerialization() ] !== null ) { return new Term( 'en', self::TEST_ITEMS[ $entityId->getSerialization() ][1] ); } else { return null; } } ); return $lookup; } public static function getExpectedMathML( $str ) { return '' . $str . ''; } }