diff --git a/src/Statement/StatementGroup.php b/src/Statement/StatementGroup.php new file mode 100644 index 00000000..65d775cd --- /dev/null +++ b/src/Statement/StatementGroup.php @@ -0,0 +1,130 @@ + + */ +class StatementGroup implements IteratorAggregate, Countable { + + /** + * @var PropertyId + */ + private $propertyId; + + /** + * @var Statement[] + */ + private $statements = array(); + + /** + * @param PropertyId|int $propertyId + */ + public function __construct( $propertyId ) { + if ( is_int( $propertyId ) ) { + $propertyId = PropertyId::newFromNumber( $propertyId ); + } + + if ( !( $propertyId instanceof PropertyId ) ) { + throw new InvalidArgumentException( '$propertyId must be an integer or an instance of PropertyId' ); + } + + $this->propertyId = $propertyId; + } + + /** + * @param Statement[]|Traversable $statements + * @throws InvalidArgumentException + */ + public function addStatements( $statements ) { + if ( !is_array( $statements ) && !( $statements instanceof Traversable ) ) { + throw new InvalidArgumentException( '$statements must be an array or an instance of Traversable' ); + } + + foreach ( $statements as $statement ) { + if ( !( $statement instanceof Statement ) ) { + throw new InvalidArgumentException( 'Every element in $statements must be an instance of Statement' ); + } + + $this->addStatement( $statement ); + } + } + + /** + * @param Statement $statement + * @throws InvalidArgumentException + */ + public function addStatement( Statement $statement ) { + if ( !$statement->getPropertyId()->equals( $this->propertyId ) ) { + throw new InvalidArgumentException( '$statement must have the property id ' . $this->propertyId->getSerialization() ); + } + + $this->statements[] = $statement; + } + + /** + * @return PropertyId + */ + public function getPropertyId() { + return $this->propertyId; + } + + /** + * @param int $rank + * @return Statement[] + */ + public function getByRank( $rank ) { + $statements = array(); + + foreach ( $this->statements as $statement ) { + if ( $statement->getRank() === $rank ) { + $statements[] = $statement; + } + } + + return $statements; + } + + /** + * @return Traversable + */ + public function getIterator() { + return new ArrayIterator( $this->statements ); + } + + /** + * @return Statement[] Numerically indexed (non-sparse) array. + */ + public function toArray() { + return $this->statements; + } + + /** + * @see Countable::count + * + * @return int + */ + public function count() { + return count( $this->statements ); + } + + /** + * @return bool + */ + public function isEmpty() { + return empty( $this->statements ); + } + +} diff --git a/tests/unit/Statement/StatementGroupTest.php b/tests/unit/Statement/StatementGroupTest.php new file mode 100644 index 00000000..20a02244 --- /dev/null +++ b/tests/unit/Statement/StatementGroupTest.php @@ -0,0 +1,139 @@ + + */ +class StatementGroupTest extends \PHPUnit_Framework_TestCase { + + public function testConstructor_numericId() { + $statementGroup = new StatementGroup( 42 ); + $this->assertEquals( new PropertyId( 'P42' ), $statementGroup->getPropertyId() ); + } + + public function testConstructor_propertyId() { + $statementGroup = new StatementGroup( new PropertyId( 'P42' ) ); + $this->assertEquals( new PropertyId( 'P42' ), $statementGroup->getPropertyId() ); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testConstructor_invalidArgument() { + new StatementGroup( 'foo' ); + } + + public function testAddStatement_validPropertyId() { + $statementGroup = new StatementGroup( 42 ); + $statement = new Statement( new PropertyNoValueSnak( 42 ) ); + $statementGroup->addStatement( $statement ); + + $this->assertEquals( array( $statement ), $statementGroup->getByRank( Statement::RANK_NORMAL ) ); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testAddStatement_invalidPropertyId() { + $statementGroup = new StatementGroup( 42 ); + $statement = new Statement( new PropertyNoValueSnak( 12 ) ); + $statementGroup->addStatement( $statement ); + } + + public function testAddStatements_validPropertyIds() { + $statementGroup = new StatementGroup( 42 ); + $foo = new Statement( new PropertyValueSnak( 42, new StringValue( 'foo' ) ) ); + $bar = new Statement( new PropertyValueSnak( 42, new StringValue( 'bar' ) ) ); + $baz = new Statement( new PropertyValueSnak( 42, new StringValue( 'baz' ) ) ); + $baz->setRank( Statement::RANK_PREFERRED ); + $statementGroup->addStatements( array( $foo, $bar, $baz ) ); + + $this->assertEquals( array(), $statementGroup->getByRank( Statement::RANK_DEPRECATED ) ); + $this->assertEquals( array( $foo, $bar ), $statementGroup->getByRank( Statement::RANK_NORMAL ) ); + $this->assertEquals( array( $baz ), $statementGroup->getByRank( Statement::RANK_PREFERRED ) ); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testAddStatements_invalidPropertyIds() { + $statementGroup = new StatementGroup( 42 ); + $foo = new Statement( new PropertyValueSnak( 42, new StringValue( 'foo' ) ) ); + $bar = new Statement( new PropertyValueSnak( 42, new StringValue( 'bar' ) ) ); + $baz = new Statement( new PropertyValueSnak( 12, new StringValue( 'baz' ) ) ); + $statementGroup->addStatements( array( $foo, $bar, $baz ) ); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testAddStatements_noStatement() { + $statementGroup = new StatementGroup( 42 ); + $statement = new Statement( new PropertyNoValueSnak( 12 ) ); + $statementGroup->addStatements( array( $statement, 'foo' ) ); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testAddStatements_noArray() { + $statementGroup = new StatementGroup( 42 ); + $statementGroup->addStatements( 'foo' ); + } + + public function testToArray() { + $statementGroup = new StatementGroup( 42 ); + $foo = new Statement( new PropertyValueSnak( 42, new StringValue( 'foo' ) ) ); + $bar = new Statement( new PropertyValueSnak( 42, new StringValue( 'bar' ) ) ); + $baz = new Statement( new PropertyValueSnak( 42, new StringValue( 'baz' ) ) ); + $statementGroup->addStatements( array( $foo, $bar, $baz ) ); + + $this->assertEquals( array( $foo, $bar, $baz ), $statementGroup->toArray() ); + } + + public function testCount_emptyGroup() { + $statementGroup = new StatementGroup( 42 ); + + $this->assertEquals( 0, $statementGroup->count() ); + } + + public function testCount_filledGroup() { + $statementGroup = new StatementGroup( 42 ); + $foo = new Statement( new PropertyValueSnak( 42, new StringValue( 'foo' ) ) ); + $bar = new Statement( new PropertyValueSnak( 42, new StringValue( 'bar' ) ) ); + $baz = new Statement( new PropertyValueSnak( 42, new StringValue( 'baz' ) ) ); + $statementGroup->addStatements( array( $foo, $bar, $baz ) ); + + $this->assertEquals( 3, $statementGroup->count() ); + } + + public function testEmpty_emptyGroup() { + $statementGroup = new StatementGroup( 42 ); + + $this->assertTrue( $statementGroup->isEmpty() ); + } + + public function testEmpty_filledGroup() { + $statementGroup = new StatementGroup( 42 ); + $foo = new Statement( new PropertyValueSnak( 42, new StringValue( 'foo' ) ) ); + $bar = new Statement( new PropertyValueSnak( 42, new StringValue( 'bar' ) ) ); + $baz = new Statement( new PropertyValueSnak( 42, new StringValue( 'baz' ) ) ); + $statementGroup->addStatements( array( $foo, $bar, $baz ) ); + + $this->assertFalse( $statementGroup->isEmpty() ); + } + +}