Skip to content

Commit

Permalink
Add typedCollect helper function (#20)
Browse files Browse the repository at this point in the history
Co-authored-by: Jérôme Gamez <jerome@gamez.name>
  • Loading branch information
StevePorter92 and jeromegamez committed Mar 17, 2024
1 parent d073e8e commit 0ced0f6
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

- Added support for Laravel 11 ([#21](https://github.com/jeromegamez/typed-collection/issues/21))
- Dropped support for Laravel 9
- Added a new `typedCollect()` helper method, based off the `collect()` helper method that comes with the Laravel framework.
([#20](https://github.com/jeromegamez/typed-collection/issues/20))

## 6.1.0 - 2023-02-17

Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ Output: A People collection only accepts objects of the following type(s): Perso
*/
```

### Helper functions

The `typedCollect()` helper function enables you to dynamically create typed collections
on the fly:

```php
$dateTimes = typedCollect([new DateTime(), new DateTime()], DateTimeInterface::class);
```

For further information on how to use Laravel Collections,
have a look at the [official documentation].

Expand Down
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
"autoload": {
"psr-4": {
"Gamez\\Illuminate\\Support\\": "src"
}
},
"files": [
"src/helpers.php"
]
},
"autoload-dev": {
"psr-4": {
Expand Down
28 changes: 28 additions & 0 deletions src/helpers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

use Gamez\Illuminate\Support\TypedCollection;

if (!function_exists('typedCollect')) {
/**
* Create an anonymous typed collection
*
* @template TKey of array-key
* @template TValue
*
* @param \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>|null $value
* @param string|string[] $types
* @return \Illuminate\Support\Collection<TKey, TValue>
*/
function typedCollect($value = [], string|array $types = [])
{
$types = is_array($types) ? $types : [$types];

$collection = new class extends TypedCollection {};

$reflectionClass = new ReflectionClass($collection);
$reflectionProperty = $reflectionClass->getProperty('allowedTypes');
$reflectionProperty->setValue($collection, $types);

return $collection::make($value);
}
}
36 changes: 36 additions & 0 deletions tests/HelpersTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Gamez\Illuminate\Support\Tests;

use DateTime;
use DateTimeInterface;
use Gamez\Illuminate\Support\Tests\ArrayableItem;
use Gamez\Illuminate\Support\TypedCollection;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;

class HelpersTest extends TestCase
{
/** @test */
public function it_cannot_be_created_with_an_unsupported_type_of_item()
{
$this->expectException(InvalidArgumentException::class);
typedCollect([new DateTime(), 'string', new DateTime()], DateTimeInterface::class);
}

/** @test */
public function it_can_be_created_with_supported_types()
{
$typedCollection = typedCollect([new DateTime(), new DateTime()], DateTimeInterface::class);
$this->assertInstanceOf(TypedCollection::class, $typedCollection);
$this->addToAssertionCount(1);
}

/** @test */
public function it_can_accept_an_array_of_types()
{
$typedCollection = typedCollect([new DateTime(), new ArrayableItem()], [DateTimeInterface::class, ArrayableItem::class]);
$this->assertInstanceOf(TypedCollection::class, $typedCollection);
$this->addToAssertionCount(1);
}
}

0 comments on commit 0ced0f6

Please sign in to comment.