Skip to content

Commit b43d104

Browse files
committed
Merge pull request #511 from wmde/revert-510-revert-508-epvs
Implement DeivedPropertyValueSnak
2 parents b0435f1 + d476fa5 commit b43d104

3 files changed

Lines changed: 256 additions & 1 deletion

File tree

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
namespace Wikibase\DataModel\Snak;
4+
5+
use DataValues\DataValue;
6+
use InvalidArgumentException;
7+
use Wikibase\DataModel\Entity\PropertyId;
8+
9+
/**
10+
* PropertyValueSnak with with derived values attached.
11+
* Derived DataValues can be used to provide infomation, for example, normalized values.
12+
*
13+
* Calls to the getType method will indicate that this is a PropertyValueSnak.
14+
*
15+
* Direct serialization of this object will not include the extra derived values.
16+
*
17+
* The hash of this object is not changed by aditional Derived values.
18+
* The hash of this object will differ from the PropertyValueSnak of this object.
19+
*
20+
* This object will ->equal other DerivedPropertyValueSnaks with the same base PropertyValueSnak.
21+
* This object will NOT ->equal any PropertyValueSnaks.
22+
* A newPropertyValueSnak method is provided for comparison convenience.
23+
*
24+
* @since 3.1
25+
*
26+
* @licence GNU GPL v2+
27+
* @author Adam Shorland
28+
*/
29+
class DerivedPropertyValueSnak extends PropertyValueSnak {
30+
31+
/**
32+
* @var DataValue[]
33+
*/
34+
private $derivedDataValues = array();
35+
36+
/**
37+
* @param PropertyId $propertyId
38+
* @param DataValue $dataValue
39+
* @param DataValue[] $derivedDataValues
40+
*/
41+
public function __construct(
42+
PropertyId $propertyId,
43+
DataValue $dataValue,
44+
array $derivedDataValues
45+
) {
46+
parent::__construct( $propertyId, $dataValue );
47+
48+
foreach ( $derivedDataValues as $key => $extensionDataValue ) {
49+
if ( !( $extensionDataValue instanceof DataValue ) || !is_string( $key ) ) {
50+
throw new InvalidArgumentException(
51+
'$derivedDataValues must be an array of DataValue objects with string keys'
52+
);
53+
}
54+
}
55+
56+
$this->derivedDataValues = $derivedDataValues;
57+
}
58+
59+
/**
60+
* @return DataValue[] with string keys
61+
*/
62+
public function getDerivedDataValues() {
63+
return $this->derivedDataValues;
64+
}
65+
66+
/**
67+
* @param string $key
68+
*
69+
* @return DataValue|null
70+
*/
71+
public function getDerivedDataValue( $key ) {
72+
if ( isset( $this->derivedDataValues[$key] ) ) {
73+
return $this->derivedDataValues[$key];
74+
}
75+
return null;
76+
}
77+
78+
/**
79+
* @return PropertyValueSnak
80+
*/
81+
public function newPropertyValueSnak() {
82+
return new PropertyValueSnak( $this->propertyId, $this->dataValue );
83+
}
84+
85+
}

src/Snak/PropertyValueSnak.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*/
1919
class PropertyValueSnak extends SnakObject {
2020

21-
private $dataValue;
21+
protected $dataValue;
2222

2323
/**
2424
* Support for passing in an EntityId instance that is not a PropertyId instance has
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
<?php
2+
3+
namespace Wikibase\DataModel\Tests\Snak;
4+
5+
use DataValues\DataValue;
6+
use DataValues\StringValue;
7+
use InvalidArgumentException;
8+
use PHPUnit_Framework_TestCase;
9+
use Wikibase\DataModel\Entity\PropertyId;
10+
use Wikibase\DataModel\Snak\DerivedPropertyValueSnak;
11+
use Wikibase\DataModel\Snak\PropertyValueSnak;
12+
13+
/**
14+
* @covers Wikibase\DataModel\Snak\DerivedPropertyValueSnak
15+
*
16+
* @group Wikibase
17+
* @group WikibaseDataModel
18+
* @group WikibaseSnak
19+
*
20+
* @licence GNU GPL v2+
21+
* @author Adam Shorland
22+
*/
23+
class DerivedPropertyValueSnakTest extends PHPUnit_Framework_TestCase {
24+
25+
/**
26+
* @dataProvider validConstructorArgumentsProvider
27+
*/
28+
public function testConstructor( $propertyId, DataValue $dataValue, array $derivedDataValues ) {
29+
$snak = new DerivedPropertyValueSnak( $propertyId, $dataValue, $derivedDataValues );
30+
$this->assertInstanceOf( 'Wikibase\DataModel\Snak\PropertyValueSnak', $snak );
31+
}
32+
33+
public function validConstructorArgumentsProvider() {
34+
return array(
35+
'No extras' => array(
36+
new PropertyId( 'P1' ),
37+
new StringValue( 'a' ),
38+
array(),
39+
),
40+
'2 extras' => array(
41+
new PropertyId( 'P9001' ),
42+
new StringValue( 'bc' ),
43+
array( 'foo' => new StringValue( 'foo' ), 'bar' => new StringValue( 'bar' ) ),
44+
),
45+
);
46+
}
47+
48+
/**
49+
* @dataProvider invalidConstructorArgumentsProvider
50+
* @expectedException InvalidArgumentException
51+
*/
52+
public function testGivenInvalidConstructorArguments_constructorThrowsException(
53+
$propertyId,
54+
DataValue $dataValue,
55+
array $derivedDataValues
56+
) {
57+
new DerivedPropertyValueSnak( $propertyId, $dataValue, $derivedDataValues );
58+
}
59+
60+
public function invalidConstructorArgumentsProvider() {
61+
return array(
62+
'fail - Integer key' => array(
63+
new PropertyId( 'P9001' ),
64+
new StringValue( 'bc' ),
65+
array( new StringValue( 'foo' ) ),
66+
),
67+
'fail - not a value' => array(
68+
new PropertyId( 'P9001' ),
69+
new StringValue( 'bc' ),
70+
array( 'foo' => 'bar' ),
71+
),
72+
);
73+
}
74+
75+
/**
76+
* This test is a safeguard to make sure hashes are not changed unintentionally.
77+
*/
78+
public function testHashStability() {
79+
$snak = new DerivedPropertyValueSnak(
80+
new PropertyId( 'P1' ),
81+
new StringValue( 'a' ),
82+
array( 'foo' => new StringValue( 'foo' ) )
83+
);
84+
$hash = $snak->getHash();
85+
86+
// @codingStandardsIgnoreStart
87+
$expected = sha1( 'C:48:"Wikibase\DataModel\Snak\DerivedPropertyValueSnak":53:{a:2:{i:0;i:1;i:1;C:22:"DataValues\StringValue":1:{a}}}' );
88+
// @codingStandardsIgnoreEnd
89+
$this->assertSame( $expected, $hash );
90+
}
91+
92+
public function testGetDerivedDataValues() {
93+
$derivedValues = array( 'foo' => new StringValue( 'foo' ), 'bar' => new StringValue( 'bar' ) );
94+
95+
$snak = new DerivedPropertyValueSnak(
96+
new PropertyId( 'P9001' ),
97+
new StringValue( 'bc' ),
98+
$derivedValues
99+
);
100+
101+
$this->assertEquals( $derivedValues, $snak->getDerivedDataValues() );
102+
}
103+
104+
public function testGetDerivedDataValue() {
105+
$foo = new StringValue( 'foo' );
106+
$bar = new StringValue( 'bar' );
107+
$derivedValues = array( 'foo' => $foo, 'bar' => $bar );
108+
109+
$snak = new DerivedPropertyValueSnak(
110+
new PropertyId( 'P9001' ),
111+
new StringValue( 'bc' ),
112+
$derivedValues
113+
);
114+
115+
$this->assertEquals( $foo, $snak->getDerivedDataValue( 'foo' ) );
116+
$this->assertEquals( $bar, $snak->getDerivedDataValue( 'bar' ) );
117+
}
118+
119+
public function testSerializationDoesNotContainDerivedValues() {
120+
$snak = new DerivedPropertyValueSnak(
121+
new PropertyId( 'P9001' ),
122+
new StringValue( 'bc' ),
123+
array( 'foo' => new StringValue( 'foo' ), 'bar' => new StringValue( 'bar' ) )
124+
);
125+
126+
$this->assertEquals(
127+
'a:2:{i:0;i:9001;i:1;C:22:"DataValues\StringValue":2:{bc}}',
128+
$snak->serialize()
129+
);
130+
}
131+
132+
public function testSnakWithDerivedValuesEqualsSnakWithoutDerivedValues() {
133+
$property = new PropertyId( 'P9001' );
134+
$value = new StringValue( 'bc' );
135+
$derivedValues = array( 'foo' => new StringValue( 'foo' ), 'bar' => new StringValue( 'bar' ) );
136+
137+
$emptyDerivedSnak = new DerivedPropertyValueSnak( $property, $value, array() );
138+
$derivedSnak = new DerivedPropertyValueSnak( $property, $value, $derivedValues );
139+
140+
$this->assertTrue( $emptyDerivedSnak->equals( $derivedSnak ) );
141+
}
142+
143+
public function testDerivedSnakDoesNoteEqualPropertyValueSnak() {
144+
$property = new PropertyId( 'P9001' );
145+
$value = new StringValue( 'bc' );
146+
$derivedValues = array( 'foo' => new StringValue( 'foo' ), 'bar' => new StringValue( 'bar' ) );
147+
148+
$propertySnak = new PropertyValueSnak( $property, $value );
149+
$emptyDerivedSnak = new DerivedPropertyValueSnak( $property, $value, array() );
150+
$derivedSnak = new DerivedPropertyValueSnak( $property, $value, $derivedValues );
151+
152+
$this->assertFalse( $propertySnak->equals( $emptyDerivedSnak ) );
153+
$this->assertFalse( $propertySnak->equals( $derivedSnak ) );
154+
}
155+
156+
public function testNewPropertyValueSnak() {
157+
$property = new PropertyId( 'P9001' );
158+
$value = new StringValue( 'bc' );
159+
$derivedValues = array( 'foo' => new StringValue( 'foo' ), 'bar' => new StringValue( 'bar' ) );
160+
161+
$propertySnak = new PropertyValueSnak( $property, $value );
162+
$derivedSnak = new DerivedPropertyValueSnak( $property, $value, $derivedValues );
163+
164+
$this->assertEquals(
165+
$propertySnak,
166+
$derivedSnak->newPropertyValueSnak()
167+
);
168+
}
169+
170+
}

0 commit comments

Comments
 (0)