Skip to content

Commit

Permalink
Add if macro (#217)
Browse files Browse the repository at this point in the history
* wip

* Fix styling

Co-authored-by: freekmurze <freekmurze@users.noreply.github.com>
  • Loading branch information
freekmurze and freekmurze authored Oct 24, 2021
1 parent af2d196 commit 9910a85
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 6 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
php: [8.0, 7.4]
php: [8.0]
laravel: [7.*, 8.*]
dependency-version: [prefer-stable]
include:
- testbench: 6.*
laravel: 8.*
- testbench: 5.*
laravel: 7.*

name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} - ${{ matrix.os }}

Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to `laravel-collection-macros` will be documented in this file

## 7.7.0 - 2021-10-24

- add `if` macro

## 7.6.0 - 2021-10-15

- Fix docblock indentation by @dwightwatson in https://github.com/spatie/laravel-collection-macros/pull/211
Expand Down
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ The package will automatically register itself.
- [`glob`](#glob)
- [`groupByModel`](#groupbymodel)
- [`head`](#head)
- [`if`](#if)
- [`ifAny`](#ifany)
- [`ifEmpty`](#ifempty)
- [`insertAfter`](#insertafter)
Expand Down Expand Up @@ -388,6 +389,47 @@ $collection = collect([]);
$collection->head(); // return null
```

### `if`

The `if` macro can help branch collection chains. This is the signature of this macro:

```php
if(mixed $if, mixed $then = null, mixed $else = null): mixed
```

`$if`, `$then` and `$else` can be any type. If a closure is passed to any of these parameters, then that closure will be executed and the macro will use its results.

When `$if` returns a truthy value, then `$then` will be returned, otherwise `$else` will be returned.

Here are some examples:

```php
collect()->if(true, then: true, else: false) // returns true
collect()->if(false, then: true, else: false) // returns false
```

When a closure is passed to `$if`, `$then` or `$else`, the entire collection will be passed as an argument to that closure.

```php
// the `then` closure will be executed
// the first element of the returned collection now contains "THIS IS THE VALUE"
$collection = collect(['this is a value'])
->if(
fn(Collection $collection) => $collection->contains('this is a value'),
then: fn(Collection $collection) => $collection->map(fn(string $item) => strtoupper($item)),
else: fn(Collection $collection) => $collection->map(fn(string $item) => Str::kebab($item))
);

// the `else` closure will be executed
// the first element of the returned collection now contains "this-is-another-value"
$collection = collect(['this is another value'])
->if(
fn(Collection $collection) => $collection->contains('this is a value'),
then: fn(Collection $collection) => $collection->map(fn(string $item) => strtoupper($item)),
else: fn(Collection $collection) => $collection->map(fn(string $item) => Str::kebab($item))
);
```

### `ifAny`

Executes the passed callable if the collection isn't empty. The entire collection will be returned.
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@
}
],
"require": {
"php": "^7.4|^8.0",
"illuminate/support": "^7.0|^8.0"
"php": "^8.0",
"illuminate/support": "^8.67"
},
"require-dev": {
"amphp/parallel": "^0.2.5",
"amphp/parallel-functions": "^0.1.3",
"mockery/mockery": "^1.4.2",
"orchestra/testbench": "^5.5|^6.5",
"orchestra/testbench": "^6.5",
"phpunit/phpunit": "^9.4.4",
"symfony/stopwatch": "^5.2"
},
Expand Down
1 change: 1 addition & 0 deletions src/CollectionMacroServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ private function macros(): array
'glob' => \Spatie\CollectionMacros\Macros\Glob::class,
'groupByModel' => \Spatie\CollectionMacros\Macros\GroupByModel::class,
'head' => \Spatie\CollectionMacros\Macros\Head::class,
'if' => \Spatie\CollectionMacros\Macros\IfMacro::class,
'ifAny' => \Spatie\CollectionMacros\Macros\IfAny::class,
'ifEmpty' => \Spatie\CollectionMacros\Macros\IfEmpty::class,
'insertAfter' => \Spatie\CollectionMacros\Macros\InsertAfter::class,
Expand Down
19 changes: 19 additions & 0 deletions src/Macros/IfMacro.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Spatie\CollectionMacros\Macros;

class IfMacro
{
public function __invoke()
{
return function (
mixed $if,
mixed $then = null,
mixed $else = null,
): mixed {
return value($if, $this)
? value($then, $this)
: value($else, $this);
};
}
}
54 changes: 54 additions & 0 deletions tests/Macros/IfTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Spatie\CollectionMacros\Test\Macros;

use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Spatie\CollectionMacros\Test\TestCase;

class IfTest extends TestCase
{
/** @test */
public function it_will_return_the_right_branch()
{
$this->assertTrue(collect()->if(true, then: true, else: false));
$this->assertFalse(collect()->if(false, then: true, else: false));
}

/**
* @test
*
* @dataProvider sentences
*/
public function it_will_pass_the_collection_to_the_branches(string $sentence, string $modifiedSentence)
{
$collection = collect([$sentence])
->if(
fn (Collection $collection) => $collection->contains('this is the value'),
then: fn (Collection $collection) => $collection->map(fn (string $item) => strtoupper($item)),
else: fn (Collection $collection) => $collection->map(fn (string $item) => Str::kebab($item))
);

$this->assertEquals($modifiedSentence, $collection[0]);
}

public function sentences(): array
{
return [
['this is the value', 'THIS IS THE VALUE'],
['this is another value', 'this-is-another-value'],
];
}

/** @test */
public function the_branches_are_optional()
{
$result = collect(['this is a value'])
->if(
false,
then: fn (Collection $collection) => 'something',
);

$this->assertNull($result);
}
}

0 comments on commit 9910a85

Please sign in to comment.