Skip to content

Commit

Permalink
Stricter interpretation of the "UniquenessConstraint", refs 1463 (#2113)
Browse files Browse the repository at this point in the history
  • Loading branch information
mwjames committed Dec 17, 2016
1 parent a23b92d commit b9e2cb0
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 2 deletions.
1 change: 1 addition & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@
"smw-pa-property-predefined_pvuc": "\"$1\" is a predefined property indicating that value assignments to a property are expected to be unique and is provided by [https://www.semantic-mediawiki.org/wiki/Help:Special_properties Semantic MediaWiki].",
"smw-pa-property-predefined-long_pvuc": "Uniqueness is established when two values are not equal in their literal representation and any violation of this constraint will be categorized as error.",
"smw-datavalue-uniqueness-constraint-error": "Property \"$1\" only permits unique value assignments and ''$2'' was already annotated in subject \"$3\".",
"smw-datavalue-uniqueness-constraint-isknown": "Property \"$1\" only permits unique value annotations, ''$2'' has already been assigned to \"$3\".",
"smw-pa-property-predefined_boo": "\"$1\" is a [[Special:Types/Boolean|type]] and predefined property provided by [https://www.semantic-mediawiki.org/wiki/Help:Special_properties Semantic MediaWiki] to represent boolean values.",
"smw-pa-property-predefined_num": "\"$1\" is a [[Special:Types/Number|type]] and predefined property provided by [https://www.semantic-mediawiki.org/wiki/Help:Special_properties Semantic MediaWiki] to represent numeric values.",
"smw-pa-property-predefined_dat": "\"$1\" is a [[Special:Types/Date|type]] and predefined property provided by [https://www.semantic-mediawiki.org/wiki/Help:Special_properties Semantic MediaWiki] to represent date values.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ class UniquenessConstraintValueValidator implements ConstraintValueValidator {
*/
private $hasConstraintViolation = false;

/**
* Tracks annotations for the current context to verify that a subject only
* contains unique assignments.
*
* @var array
*/
private static $inMemoryAnnotationTracer = array();

/**
* @since 2.4
*
Expand Down Expand Up @@ -132,6 +140,25 @@ public function validate( $dataValue ) {

$this->hasConstraintViolation = true;
}

// Already assigned!
if ( !$this->hasConstraintViolation && ( $isKnownBy = $this->isKnownBy( $hash, $dataValue ) ) !== false ) {
$dataValue->addErrorMsg(
array(
'smw-datavalue-uniqueness-constraint-isknown',
$property->getLabel(),
$dataValue->getWikiValue(),
$isKnownBy->getTitle()->getPrefixedText()
)
);

$this->hasConstraintViolation = true;
}

}

private function canValidate( $dataValue ) {
return $dataValue instanceof DataValue && $dataValue->getProperty() !== null && $dataValue->getContextPage() !== null && $dataValue->isEnabledFeature( SMW_DV_PVUC );
}

private function tryFindMatchResultFor( $hash, $dataValue ) {
Expand Down Expand Up @@ -182,8 +209,24 @@ private function tryFindMatchResultFor( $hash, $dataValue ) {
return $page;
}

private function canValidate( $dataValue ) {
return $dataValue instanceof DataValue && $dataValue->getProperty() !== null && $dataValue->getContextPage() !== null && $dataValue->isEnabledFeature( SMW_DV_PVUC );
private function isKnownBy( $valueHash, $dataValue ) {

$contextPage = $dataValue->getContextPage();

if ( $contextPage === null ) {
return false;
}

$key = $dataValue->getProperty()->getKey();
$hash = $contextPage->getHash();

if ( isset( self::$inMemoryAnnotationTracer[$hash][$key] ) && self::$inMemoryAnnotationTracer[$hash][$key] !== $valueHash ) {
return $contextPage;
} else {
self::$inMemoryAnnotationTracer[$hash][$key] = $valueHash;
}

return false;
}

}
72 changes: 72 additions & 0 deletions tests/phpunit/Integration/JSONScript/TestCases/p-0443.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"description": "Test conditions and strict constraint validations for uniqueness `_PVUC` (#1463, `wgContLang=en`, `wgLang=en`, `smwgDVFeatures`)",
"setup": [
{
"namespace": "SMW_NS_PROPERTY",
"page": "Has uniqueness one",
"contents": "[[Has type::Text]] [[Has uniqueness constraint::true]]"
},
{
"namespace": "SMW_NS_PROPERTY",
"page": "Has uniqueness two",
"contents": "[[Has type::Text]] [[Has uniqueness constraint::true]]"
},
{
"page": "Example/P0443/1",
"contents": "[[Has uniqueness one::Allowed one]] [[Has uniqueness one::Not permitted]] [[Has uniqueness two::Allowed two]] [[Has uniqueness two::Not permitted]]"
},
{
"page": "Example/P0443/2",
"contents": "[[Has uniqueness one::1111]] {{#ask: [[Has uniqueness one::1111]] |link=none }}"
}
],
"tests": [
{
"type": "parser",
"about": "#0 (verify uniqueness for only one assignment per property)",
"subject": "Example/P0443/1",
"store": {
"clear-cache": true
},
"assert-store": {
"semantic-data": {
"strictPropertyValueMatch": false,
"propertyCount": 5,
"propertyKeys": [
"_MDAT",
"_SKEY",
"_ERRC",
"Has uniqueness one",
"Has uniqueness two"
],
"propertyValues": [
"Allowed one",
"Allowed two"
]
}
}
},
{
"type": "parser",
"about": "#1 (verify declared unique value doesn't interfere with #ask within the same page)",
"subject": "Example/P0443/2",
"assert-output": {
"to-contain": [
"<p>1111 Example/P0443/2"
]
}
}
],
"settings": {
"smwgDVFeatures": [
"SMW_DV_PVUC"
],
"wgContLang": "en",
"wgLang": "en"
},
"meta": {
"version": "2",
"is-incomplete": false,
"debug": false
}
}
3 changes: 3 additions & 0 deletions tests/phpunit/Utils/Validators/SemanticDataValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ private function assertThatSemanticDataIsIndeedEmpty( SemanticData $semanticData
}

private function assertContainsPropertyKeys( $keys, DIProperty $property ) {

$keys = str_replace( " " , "_", $keys );

$this->assertContains(
$property->getKey(),
$keys,
Expand Down

0 comments on commit b9e2cb0

Please sign in to comment.