Skip to content

Commit

Permalink
Merge pull request #28 from jobapis/collection-upgrade
Browse files Browse the repository at this point in the history
Collection upgrade, updating getSource method
  • Loading branch information
karllhughes committed Dec 1, 2016
2 parents bffdc6a + cd4d7e0 commit f7baef0
Show file tree
Hide file tree
Showing 5 changed files with 288 additions and 3 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Changelog
All Notable changes to `jobs-common` will be documented in this file

## 2.1.0 - 2016-12-01

### Added
- New methods to Collection object: `addCollection`, `filter`, `orderBy`, and `truncate`.

### Fixed
- `getSource` method was returning the source with the suffix `Provider` since the v2 upgrade. I created a method to remove `Provider` from the end of the string if present.

## 2.0.2 - 2016-11-01

### Fixed
Expand Down
104 changes: 104 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,31 @@ public function add($item, $key = null)
return $this;
}

/**
* Append a collection to this collection.
*
* @param Collection $collection
*
* @return $this
*/
public function addCollection(Collection $collection)
{
// If there are jobs, add them to the collection
if ($collection->count()) {
foreach ($collection->all() as $job) {
$this->add($job);
}
}
// If there are errors, add them to the collection
if ($collection->getErrors()) {
foreach ($collection->getErrors() as $error) {
$this->addError($error);
}
}

return $this;
}

/**
* Add error to collection
*
Expand Down Expand Up @@ -101,6 +126,37 @@ public function delete($key)
return $this;
}

/**
* Filter items by a field having a specific value.
*
* @param string $field
* @param string $value
* @param string $operator
*
* @return $this
*/
public function filter($field, $value, $operator = '=')
{
$this->items = array_filter(
$this->items,
function ($item) use ($field, $value, $operator) {
if (!isset($item->{$field})) {
throw new \Exception("Property not defined.");
}
if ($operator == '>') {
return $item->{$field} > $value;
} elseif ($operator == '<') {
return $item->{$field} < $value;
} elseif ($operator == '=') {
return $item->{$field} == $value;
}
return false;
}
);

return $this;
}

/**
* Get item from collection at specific key
*
Expand Down Expand Up @@ -128,4 +184,52 @@ public function getErrors()
{
return $this->errors;
}

/**
* Order items by a field value.
*
* @param string $orderBy
* @param string $order
*
* @return $this
*/
public function orderBy($orderBy, $order = 'desc')
{
usort(
$this->items,
function ($item1, $item2) use ($orderBy, $order) {
if (!isset($item1->{$orderBy}) || !isset($item2->{$orderBy})) {
throw new \Exception("Property not defined.");
}
// If the two items are equal, return 0
if ($item1->{$orderBy} == $item2->{$orderBy}) {
return 0;
}
// If ascending, test whether Item 1 is less than Item 2
if ($order === 'asc') {
return $item1->{$orderBy} < $item2->{$orderBy} ? -1 : 1;
}
// Else assuming descending.
return $item1->{$orderBy} > $item2->{$orderBy} ? -1 : 1;
}
);

return $this;
}

/**
* Truncate the items to a maximum number of results.
*
* @param null $max
*
* @return $this
*/
public function truncate($max = null)
{
if ($max) {
$this->items = array_slice($this->items, 0, $max);
}

return $this;
}
}
29 changes: 27 additions & 2 deletions src/Providers/AbstractProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,16 @@ public function getJobs()
*/
public function getSource()
{
$ref = new \ReflectionClass(get_class($this));
$classSuffix = "Provider";

return $ref->getShortName();
$className = (new \ReflectionClass(get_class($this)))->getShortName();

// Strip off the suffix from the provider
if ($this->stringEndsWith($className, $classSuffix)) {
$className = substr($className, 0, strlen($classSuffix));
}

return $className;
}

/**
Expand Down Expand Up @@ -353,4 +360,22 @@ private function parseAsXml($string)

return [];
}

/**
* Determine whether a string ends with another string
*
* @param $string
* @param $test
*
* @return bool
*/
private function stringEndsWith($string, $test)
{
$stringLen = strlen($string);
$testLen = strlen($test);
if ($testLen > $stringLen) {
return false;
}
return substr_compare($string, $test, $stringLen - $testLen, $testLen) === 0;
}
}
148 changes: 148 additions & 0 deletions tests/src/CollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,152 @@ public function testItFailsToDeleteItemWithoutValidKey()

$this->assertEquals($message, end($errors));
}

public function testItCanAddCollectionWhenCollectionHasItemsAndErrors()
{
$error = uniqid();

// Add an item to the test collection
$this->collection->add($this->getItem());

// Create a new collection with 2 items and 1 error
$collection = (new Collection())
->add($this->getItem())
->add($this->getItem())
->addError($error);

$this->collection->addCollection($collection);

$this->assertEquals(3, $this->collection->count());
$this->assertEquals($error, $this->collection->getErrors()[0]);
}

public function testItCanAddCollectionWhenCollectionHasNoItems()
{
$error = uniqid();

// Add an item to the test collection
$this->collection->add($this->getItem());

// Create a new collection with 1 error
$collection = (new Collection())
->addError($error);

$this->collection->addCollection($collection);

$this->assertEquals(1, $this->collection->count());
$this->assertEquals($error, $this->collection->getErrors()[0]);
}

public function testItCanFilterItemsWhenFieldExists()
{
// Add some items to the test collection
$item = $this->getItem();
$this->collection->add($item)
->add($this->getItem());

// Filter
$this->collection->filter('id', $item->id);

// Test the results
$this->assertEquals(1, $this->collection->count());
$this->assertEquals($item, $this->collection->get(0));
}

/**
* @expectedException \Exception
* @expectedExceptionMessage Property not defined.
*/
public function testItCannotFilterItemsWhenFieldNotExists()
{
// Add some items to the test collection
$item = $this->getItem();
$this->collection->add($item)
->add($this->getItem());

// Filter
$this->collection->filter(uniqid(), $item->id);
}

public function testItCanOrderItemsWhenFieldExists()
{
// Add some items to the test collection
$this->collection
->add($this->getItem())
->add($this->getItem())
->add($this->getItem());

// Filter
$this->collection->orderBy('id');

// Test the results
$this->assertEquals(3, $this->collection->count());
$prevItem = null;
foreach($this->collection->all() as $item) {
if ($prevItem) {
$this->assertLessThan($prevItem, $item);
}
$prevItem = $item;
}
}

public function testItCanOrderItemsAscWhenFieldExists()
{
// Add some items to the test collection
$this->collection
->add($this->getItem())
->add($this->getItem())
->add($this->getItem());

// Filter
$this->collection->orderBy('id', 'asc');

// Test the results
$this->assertEquals(3, $this->collection->count());
$prevItem = null;
foreach($this->collection->all() as $item) {
if ($prevItem) {
$this->assertGreaterThan($prevItem, $item);
}
$prevItem = $item;
}
}

/**
* @expectedException \Exception
* @expectedExceptionMessage Property not defined.
*/
public function testItCannotOrderItemsWhenFieldNotExists()
{
// Add some items to the test collection
$this->collection
->add($this->getItem())
->add($this->getItem())
->add($this->getItem());

// Filter
$this->collection->orderBy(uniqid());
}

public function testItCanTruncateCollection()
{
// Add some items to the test collection
$this->collection
->add($this->getItem())
->add($this->getItem())
->add($this->getItem());

// Filter
$this->collection->truncate(1);

// Test the results
$this->assertEquals(1, $this->collection->count());
}

private function getItem()
{
return (object) [
'id' => uniqid(),
];
}
}
2 changes: 1 addition & 1 deletion tests/src/ProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public function testItCannotGetJobsWhenInvalidQueryProvided()

public function testItCanGetSource()
{
$this->assertEquals('ConcreteProvider', $this->client->getSource());
$this->assertEquals('Concrete', $this->client->getSource());
}

public function testItCanParseDefaultAttributes()
Expand Down

0 comments on commit f7baef0

Please sign in to comment.