Lucas Werkmeister (WMDE) has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/402884 )

Change subject: Add scope support to DelegatingConstraintChecker
......................................................................

Add scope support to DelegatingConstraintChecker

The “constraint scope” parameter’s validity is checked along with other
common parameters like “exception to constraint” or “constraint status”,
and when it comes to actually checking a constraint,
DelegatingConstraintChecker also takes care of assigning the default
scope and testing whether a constraint can even be checked on a certain
context.

Bug: T183542
Change-Id: Ie9d7c1c9e7a57d0e03ca0cb0f96d47d0f1869921
---
M src/ConstraintCheck/DelegatingConstraintChecker.php
M tests/phpunit/Api/CheckConstraintsTest.php
M tests/phpunit/DelegatingConstraintCheckerTest.php
3 files changed, 237 insertions(+), 0 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikibaseQualityConstraints
 refs/changes/84/402884/1

diff --git a/src/ConstraintCheck/DelegatingConstraintChecker.php 
b/src/ConstraintCheck/DelegatingConstraintChecker.php
index cb71871..eb88ab5 100644
--- a/src/ConstraintCheck/DelegatingConstraintChecker.php
+++ b/src/ConstraintCheck/DelegatingConstraintChecker.php
@@ -190,6 +190,42 @@
                return [];
        }
 
+       private function getAllowedContextTypes( Constraint $constraint ) {
+               if ( !array_key_exists( $constraint->getConstraintTypeItemId(), 
$this->checkerMap ) ) {
+                       return [
+                               Context::TYPE_STATEMENT,
+                               Context::TYPE_QUALIFIER,
+                               Context::TYPE_REFERENCE,
+                       ];
+               }
+
+               return array_keys( array_filter(
+                       
$this->checkerMap[$constraint->getConstraintTypeItemId()]->getSupportedContextTypes(),
+                       function ( array $supportedContextTypes ) {
+                               list( $resultStatus, $default ) = 
$supportedContextTypes;
+                               return $resultStatus !== 
CheckResult::STATUS_NOT_IN_SCOPE;
+                       }
+               ) );
+       }
+
+       private function getDefaultContextTypes( Constraint $constraint ) {
+               if ( !array_key_exists( $constraint->getConstraintTypeItemId(), 
$this->checkerMap ) ) {
+                       return [
+                               Context::TYPE_STATEMENT,
+                               Context::TYPE_QUALIFIER,
+                               Context::TYPE_REFERENCE,
+                       ];
+               }
+
+               return array_keys( array_filter(
+                       
$this->checkerMap[$constraint->getConstraintTypeItemId()]->getSupportedContextTypes(),
+                       function ( array $supportedContextTypes ) {
+                               list( $resultStatus, $default ) = 
$supportedContextTypes;
+                               return $default;
+                       }
+               ) );
+       }
+
        /**
         * Like ConstraintChecker::checkConstraintParameters,
         * but for meta-parameters common to all checkers.
@@ -214,6 +250,15 @@
                }
                try {
                        
$this->constraintParameterParser->parseConstraintStatusParameter( 
$constraintParameters );
+               } catch ( ConstraintParameterException $e ) {
+                       $problems[] = $e;
+               }
+               try {
+                       
$this->constraintParameterParser->parseConstraintScopeParameter(
+                               $constraintParameters,
+                               $constraint->getConstraintTypeItemId(),
+                               $this->getAllowedContextTypes( $constraint )
+                       );
                } catch ( ConstraintParameterException $e ) {
                        $problems[] = $e;
                }
@@ -505,6 +550,30 @@
        private function getCheckResultFor( Context $context, Constraint 
$constraint ) {
                if ( array_key_exists( $constraint->getConstraintTypeItemId(), 
$this->checkerMap ) ) {
                        $checker = 
$this->checkerMap[$constraint->getConstraintTypeItemId()];
+                       $result = null;
+
+                       try {
+                               $checkedContextTypes = 
$this->constraintParameterParser->parseConstraintScopeParameter(
+                                       $constraint->getConstraintParameters(),
+                                       $constraint->getConstraintTypeItemId()
+                               );
+                       } catch ( ConstraintParameterException $e ) {
+                               $result = new CheckResult( $context, 
$constraint, [], CheckResult::STATUS_BAD_PARAMETERS, $e->getMessage() );
+                       }
+                       if ( $checkedContextTypes === null ) {
+                               $checkedContextTypes = 
$this->getDefaultContextTypes( $constraint );
+                       }
+                       if ( !in_array( $context->getType(), 
$checkedContextTypes ) ) {
+                               $result = new CheckResult( $context, 
$constraint, [], CheckResult::STATUS_NOT_IN_SCOPE, null );
+                       }
+                       if ( 
$checker->getSupportedContextTypes()[$context->getType()][0] === 
CheckResult::STATUS_TODO ) {
+                               $result = new CheckResult( $context, 
$constraint, [], CheckResult::STATUS_TODO, null );
+                       }
+
+                       if ( $result !== null ) {
+                               $this->addMetadata( $result );
+                               return $result;
+                       }
 
                        $startTime = microtime( true );
                        try {
diff --git a/tests/phpunit/Api/CheckConstraintsTest.php 
b/tests/phpunit/Api/CheckConstraintsTest.php
index 4f1b9a3..6570d6f 100644
--- a/tests/phpunit/Api/CheckConstraintsTest.php
+++ b/tests/phpunit/Api/CheckConstraintsTest.php
@@ -110,6 +110,10 @@
                                'WBQualityConstraintsPropertyConstraintId' => 
'P1',
                                'WBQualityConstraintsExceptionToConstraintId' 
=> 'P2',
                                'WBQualityConstraintsConstraintStatusId' => 
'P3',
+                               'WBQualityConstraintsConstraintScopeId' => 'P4',
+                               
'WBQualityConstraintsConstraintCheckedOnMainValueId' => 'Q1',
+                               
'WBQualityConstraintsConstraintCheckedOnQualifiersId' => 'Q2',
+                               
'WBQualityConstraintsConstraintCheckedOnReferencesId' => 'Q3',
                                'WBQualityConstraintsCheckDurationInfoSeconds' 
=> 1.0,
                                
'WBQualityConstraintsCheckDurationWarningSeconds' => 10.0,
                                'WBQualityConstraintsIncludeDetailInApi' => 
true,
diff --git a/tests/phpunit/DelegatingConstraintCheckerTest.php 
b/tests/phpunit/DelegatingConstraintCheckerTest.php
index 592adbd..fd9969c 100644
--- a/tests/phpunit/DelegatingConstraintCheckerTest.php
+++ b/tests/phpunit/DelegatingConstraintCheckerTest.php
@@ -15,9 +15,12 @@
 use Wikibase\Repo\Tests\NewItem;
 use Wikibase\Repo\Tests\NewStatement;
 use WikibaseQuality\ConstraintReport\Constraint;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\ConstraintChecker;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\Context;
 use 
WikibaseQuality\ConstraintReport\ConstraintCheck\DelegatingConstraintChecker;
 use 
WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterException;
 use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\LoggingHelper;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResult;
 use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\NullResult;
 use WikibaseQuality\ConstraintReport\ConstraintReportFactory;
 use WikibaseQuality\ConstraintReport\Tests\ConstraintParameters;
@@ -627,4 +630,165 @@
                );
        }
 
+       public function testSupportedContextTypes_NotSupported() {
+               $checker = $this->getMock( ConstraintChecker::class );
+               $checker->method( 'getSupportedContextTypes' )
+                       ->willReturn( [
+                               Context::TYPE_STATEMENT => [ 
CheckResult::STATUS_NOT_IN_SCOPE, false ],
+                       ] );
+               $checker->expects( $this->never() )->method( 'checkConstraint' 
);
+               $lookup = new InMemoryEntityLookup();
+               $q2 = new ItemId( 'Q2' );
+               $lookup->addEntity(
+                       NewItem::withId( $q2 )
+                               ->andStatement( NewStatement::noValueFor( 'P1' 
) )
+                               ->build()
+               );
+               $delegatingConstraintChecker = new DelegatingConstraintChecker(
+                       $lookup,
+                       [ 'Q1' => $checker ],
+                       new InMemoryConstraintLookup( [
+                               new Constraint( '', new PropertyId( 'P1' ), 
'Q1', [] )
+                       ] ),
+                       $this->getConstraintParameterParser(),
+                       new StatementGuidParser( new ItemIdParser() ),
+                       $this->getMockBuilder( LoggingHelper::class )
+                               ->disableOriginalConstructor()
+                               ->getMock(),
+                       true,
+                       true,
+                       []
+               );
+
+               $results = 
$delegatingConstraintChecker->checkAgainstConstraintsOnEntityId( $q2 );
+
+               $this->assertCount( 1, $results );
+               $this->assertNotInScope( $results[0] );
+       }
+
+       public function testSupportedContextTypes_NotImplemented() {
+               $checker = $this->getMock( ConstraintChecker::class );
+               $checker->method( 'getSupportedContextTypes' )
+                       ->willReturn( [
+                               Context::TYPE_STATEMENT => [ 
CheckResult::STATUS_TODO, true ],
+                       ] );
+               $checker->expects( $this->never() )->method( 'checkConstraint' 
);
+               $lookup = new InMemoryEntityLookup();
+               $q2 = new ItemId( 'Q2' );
+               $lookup->addEntity(
+                       NewItem::withId( $q2 )
+                               ->andStatement( NewStatement::noValueFor( 'P1' 
) )
+                               ->build()
+               );
+               $delegatingConstraintChecker = new DelegatingConstraintChecker(
+                       $lookup,
+                       [ 'Q1' => $checker ],
+                       new InMemoryConstraintLookup( [
+                               new Constraint( '', new PropertyId( 'P1' ), 
'Q1', [] )
+                       ] ),
+                       $this->getConstraintParameterParser(),
+                       new StatementGuidParser( new ItemIdParser() ),
+                       $this->getMockBuilder( LoggingHelper::class )
+                               ->disableOriginalConstructor()
+                               ->getMock(),
+                       true,
+                       true,
+                       []
+               );
+
+               $results = 
$delegatingConstraintChecker->checkAgainstConstraintsOnEntityId( $q2 );
+
+               $this->assertCount( 1, $results );
+               $this->assertTodo( $results[0] );
+       }
+
+       public function testSupportedContextTypes_DefaultScope() {
+               $checker = $this->getMock( ConstraintChecker::class );
+               $checker->method( 'getSupportedContextTypes' )
+                       ->willReturn( [
+                               Context::TYPE_STATEMENT => [ 
CheckResult::STATUS_COMPLIANCE, false ],
+                               Context::TYPE_QUALIFIER => [ 
CheckResult::STATUS_COMPLIANCE, true ],
+                       ] );
+               $checker->expects( $this->once() )
+                       ->method( 'checkConstraint' )
+                       ->willReturnCallback( function( Context $context, 
Constraint $constraint ) {
+                               $this->assertSame( Context::TYPE_QUALIFIER, 
$context->getType() );
+                               return new CheckResult( $context, $constraint );
+                       } );
+               $lookup = new InMemoryEntityLookup();
+               $q2 = new ItemId( 'Q2' );
+               $lookup->addEntity(
+                       NewItem::withId( $q2 )
+                               ->andStatement(
+                                       NewStatement::noValueFor( 'P1' )
+                                               ->withQualifier( 'P1', 'value' )
+                               )
+                               ->build()
+               );
+               $delegatingConstraintChecker = new DelegatingConstraintChecker(
+                       $lookup,
+                       [ 'Q1' => $checker ],
+                       new InMemoryConstraintLookup( [
+                               new Constraint( '', new PropertyId( 'P1' ), 
'Q1', [] )
+                       ] ),
+                       $this->getConstraintParameterParser(),
+                       new StatementGuidParser( new ItemIdParser() ),
+                       $this->getMockBuilder( LoggingHelper::class )
+                               ->disableOriginalConstructor()
+                               ->getMock(),
+                       true,
+                       true,
+                       []
+               );
+
+               $results = 
$delegatingConstraintChecker->checkAgainstConstraintsOnEntityId( $q2 );
+       }
+
+       public function testSupportedContextTypes_ExplicitScope() {
+               $checker = $this->getMock( ConstraintChecker::class );
+               $checker->method( 'getSupportedContextTypes' )
+                       ->willReturn( [
+                               Context::TYPE_STATEMENT => [ 
CheckResult::STATUS_COMPLIANCE, false ],
+                               Context::TYPE_QUALIFIER => [ 
CheckResult::STATUS_COMPLIANCE, true ],
+                       ] );
+               $checker->expects( $this->once() )
+                       ->method( 'checkConstraint' )
+                       ->willReturnCallback( function( Context $context, 
Constraint $constraint ) {
+                               $this->assertSame( Context::TYPE_STATEMENT, 
$context->getType() );
+                               return new CheckResult( $context, $constraint );
+                       } );
+               $lookup = new InMemoryEntityLookup();
+               $q2 = new ItemId( 'Q2' );
+               $lookup->addEntity(
+                       NewItem::withId( $q2 )
+                               ->andStatement(
+                                       NewStatement::noValueFor( 'P1' )
+                                               ->withQualifier( 'P1', 'value' )
+                               )
+                               ->build()
+               );
+               $delegatingConstraintChecker = new DelegatingConstraintChecker(
+                       $lookup,
+                       [ 'Q1' => $checker ],
+                       new InMemoryConstraintLookup( [
+                               new Constraint(
+                                       '',
+                                       new PropertyId( 'P1' ),
+                                       'Q1',
+                                       $this->scopeParameter( [ 
Context::TYPE_STATEMENT ] )
+                               )
+                       ] ),
+                       $this->getConstraintParameterParser(),
+                       new StatementGuidParser( new ItemIdParser() ),
+                       $this->getMockBuilder( LoggingHelper::class )
+                               ->disableOriginalConstructor()
+                               ->getMock(),
+                       true,
+                       true,
+                       []
+               );
+
+               $results = 
$delegatingConstraintChecker->checkAgainstConstraintsOnEntityId( $q2 );
+       }
+
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/402884
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie9d7c1c9e7a57d0e03ca0cb0f96d47d0f1869921
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/WikibaseQualityConstraints
Gerrit-Branch: master
Gerrit-Owner: Lucas Werkmeister (WMDE) <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to