Implement CollectionIterator

This commit is contained in:
Jeremy Dormitzer 2019-04-11 20:45:32 -04:00
parent 5bb70fa7e5
commit 97222e6749
2 changed files with 235 additions and 0 deletions

View File

@ -0,0 +1,104 @@
<?php
namespace ActivityPub\Objects;
use ActivityPub\Entities\ActivityPubObject;
use InvalidArgumentException;
use Iterator;
class CollectionIterator implements Iterator
{
/**
* @var ActivityPubObject
*/
private $collection;
/**
* @var ActivityPubObject
*/
private $items;
/**
* @var int
*/
private $idx;
public function __construct( ActivityPubObject $collection )
{
if ( ! ( $collection->hasField('type') &&
in_array( $collection['type'], array( 'Collection', 'OrderedCollection' ) ) ) ) {
throw new InvalidArgumentException('Must pass a collection');
}
$itemsField = 'items';
if ( $collection['type'] == 'OrderedCollection' ) {
$itemsField = 'orderedItems';
}
$this->items = $collection[$itemsField];
if ( ! $this->items ) {
throw new InvalidArgumentException('Collection must have an items or orderedItems field!');
}
$this->collection = $collection;
$this->idx = 0;
}
public static function iterateCollection( ActivityPubObject $collection )
{
return new CollectionIterator( $collection );
}
/**
* Return the current element
* @link https://php.net/manual/en/iterator.current.php
* @return mixed Can return any type.
* @since 5.0.0
*/
public function current()
{
return $this->items[$this->idx];
}
/**
* Move forward to next element
* @link https://php.net/manual/en/iterator.next.php
* @return void Any returned value is ignored.
* @since 5.0.0
*/
public function next()
{
$this->idx += 1;
}
/**
* Return the key of the current element
* @link https://php.net/manual/en/iterator.key.php
* @return mixed scalar on success, or null on failure.
* @since 5.0.0
*/
public function key()
{
return $this->idx;
}
/**
* Checks if current position is valid
* @link https://php.net/manual/en/iterator.valid.php
* @return boolean The return value will be casted to boolean and then evaluated.
* Returns true on success or false on failure.
* @since 5.0.0
*/
public function valid()
{
return $this->items->hasField($this->idx);
}
/**
* Rewind the Iterator to the first element
* @link https://php.net/manual/en/iterator.rewind.php
* @return void Any returned value is ignored.
* @since 5.0.0
*/
public function rewind()
{
$this->idx = 0;
}
}

View File

@ -0,0 +1,131 @@
<?php
namespace ActivityPub\Test\Objects;
use ActivityPub\Entities\ActivityPubObject;
use ActivityPub\Objects\CollectionIterator;
use ActivityPub\Test\ActivityPubTest;
use ActivityPub\Test\TestConfig\APTestCase;
use ActivityPub\Test\TestUtils\TestActivityPubObject;
class CollectionIteratorTest extends APTestCase
{
public function provideTestCollectionIterator()
{
return array(
array( array(
'id' => 'basicIteration',
'collection' => TestActivityPubObject::fromArray( array(
'id' => 'mycollection',
'type' => 'Collection',
'items' => array(
array(
'id' => 'item1',
),
array(
'id' => 'item2',
),
array(
'id' => 'item3',
),
)
) ),
'expectedItems' => array(
array(
'id' => 'item1',
),
array(
'id' => 'item2',
),
array(
'id' => 'item3',
),
),
) ),
array( array(
'id' => 'orderedCollection',
'collection' => TestActivityPubObject::fromArray( array(
'id' => 'mycollection',
'type' => 'OrderedCollection',
'orderedItems' => array(
array(
'id' => 'item1',
),
array(
'id' => 'item2',
),
array(
'id' => 'item3',
),
)
) ),
'expectedItems' => array(
array(
'id' => 'item1',
),
array(
'id' => 'item2',
),
array(
'id' => 'item3',
),
),
) ),
array( array(
'id' => 'orderedCollectionWrongItems',
'collection' => TestActivityPubObject::fromArray( array(
'id' => 'mycollection',
'type' => 'OrderedCollection',
'items' => array(
array(
'id' => 'item1',
),
array(
'id' => 'item2',
),
array(
'id' => 'item3',
),
)
) ),
'expectedException' => \InvalidArgumentException::class,
) ),
array( array(
'id' => 'unorderedCollectionWrongItems',
'collection' => TestActivityPubObject::fromArray( array(
'id' => 'mycollection',
'type' => 'Collection',
'orderedItems' => array(
array(
'id' => 'item1',
),
array(
'id' => 'item2',
),
array(
'id' => 'item3',
),
)
) ),
'expectedException' => \InvalidArgumentException::class,
) ),
);
}
/**
* @dataProvider provideTestCollectionIterator
*/
public function testCollectionIterator( $testCase )
{
$this->setExpectedException( null );
if ( array_key_exists( 'expectedException', $testCase ) ) {
$this->setExpectedException( $testCase['expectedException'] );
}
foreach ( CollectionIterator::iterateCollection( $testCase['collection'] ) as $idx => $item ) {
if ( $item instanceof ActivityPubObject ) {
$item = $item->asArray();
}
$this->assertEquals( $testCase['expectedItems'][$idx], $item, "Error on test $testCase[id]" );
}
}
}