Skip to content

Commit

Permalink
[9.x] Add Conditionable support for callback conditions (#37667)
Browse files Browse the repository at this point in the history
* Add `Conditionable` support for callback conditions

* Update DocBlocks in `Enumerable` to match `Conditionable`

* Update uses

* Add to collection higher order proxy
  • Loading branch information
JosephSilber authored Jun 17, 2021
1 parent 691fe57 commit b7f0359
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/Illuminate/Collections/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,7 @@ public function sole($key = null, $operator = null, $value = null)
? $this->operatorForWhere(...func_get_args())
: $key;

$items = $this->when($filter)->filter($filter);
$items = $this->unless($filter == null)->filter($filter);

if ($items->isEmpty()) {
throw new ItemNotFoundException;
Expand Down
4 changes: 2 additions & 2 deletions src/Illuminate/Collections/Enumerable.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ public function except($keys);
public function filter(callable $callback = null);

/**
* Apply the callback if the value is truthy.
* Apply the callback if the given "value" is (or resolves to) truthy.
*
* @param bool $value
* @param callable|null $callback
Expand Down Expand Up @@ -296,7 +296,7 @@ public function whenEmpty(callable $callback, callable $default = null);
public function whenNotEmpty(callable $callback, callable $default = null);

/**
* Apply the callback if the value is falsy.
* Apply the callback if the given "value" is (or resolves to) truthy.
*
* @param bool $value
* @param callable $callback
Expand Down
2 changes: 1 addition & 1 deletion src/Illuminate/Collections/LazyCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,7 @@ public function sole($key = null, $operator = null, $value = null)
: $key;

return $this
->when($filter)
->unless($filter == null)
->filter($filter)
->take(2)
->collect()
Expand Down
10 changes: 7 additions & 3 deletions src/Illuminate/Collections/Traits/EnumeratesValues.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,18 @@
* @property-read HigherOrderCollectionProxy $min
* @property-read HigherOrderCollectionProxy $partition
* @property-read HigherOrderCollectionProxy $reject
* @property-read HigherOrderCollectionProxy $skipUntil
* @property-read HigherOrderCollectionProxy $skipWhile
* @property-read HigherOrderCollectionProxy $some
* @property-read HigherOrderCollectionProxy $sortBy
* @property-read HigherOrderCollectionProxy $sortByDesc
* @property-read HigherOrderCollectionProxy $skipUntil
* @property-read HigherOrderCollectionProxy $skipWhile
* @property-read HigherOrderCollectionProxy $sum
* @property-read HigherOrderCollectionProxy $takeUntil
* @property-read HigherOrderCollectionProxy $takeWhile
* @property-read HigherOrderCollectionProxy $unique
* @property-read HigherOrderCollectionProxy $unless
* @property-read HigherOrderCollectionProxy $until
* @property-read HigherOrderCollectionProxy $when
*/
trait EnumeratesValues
{
Expand Down Expand Up @@ -76,7 +78,9 @@ trait EnumeratesValues
'takeUntil',
'takeWhile',
'unique',
'unless',
'until',
'when',
];

/**
Expand Down Expand Up @@ -138,7 +142,7 @@ public static function times($number, callable $callback = null)
}

return static::range(1, $number)
->when($callback)
->unless($callback == null)
->map($callback);
}

Expand Down
9 changes: 7 additions & 2 deletions src/Illuminate/Support/Traits/Conditionable.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

namespace Illuminate\Support\Traits;

use Closure;
use Illuminate\Support\HigherOrderWhenProxy;

trait Conditionable
{
/**
* Apply the callback if the given "value" is truthy.
* Apply the callback if the given "value" is (or resolves to) truthy.
*
* @param mixed $value
* @param callable|null $callback
Expand All @@ -17,6 +18,8 @@ trait Conditionable
*/
public function when($value, callable $callback = null, callable $default = null)
{
$value = $value instanceof Closure ? $value($this) : $value;

if (! $callback) {
return new HigherOrderWhenProxy($this, $value);
}
Expand All @@ -31,7 +34,7 @@ public function when($value, callable $callback = null, callable $default = null
}

/**
* Apply the callback if the given "value" is falsy.
* Apply the callback if the given "value" is (or resolves to) falsy.
*
* @param mixed $value
* @param callable|null $callback
Expand All @@ -41,6 +44,8 @@ public function when($value, callable $callback = null, callable $default = null
*/
public function unless($value, callable $callback = null, callable $default = null)
{
$value = $value instanceof Closure ? $value($this) : $value;

if (! $callback) {
return new HigherOrderWhenProxy($this, ! $value);
}
Expand Down
24 changes: 24 additions & 0 deletions tests/Support/SupportCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4391,6 +4391,30 @@ public function testHigherOrderWhenAndUnless($collection)
$this->assertSame(['michael', 'tom', 'chris', 'adam'], $data->toArray());
}

/**
* @dataProvider collectionClassProvider
*/
public function testHigherOrderWhenAndUnlessWithProxy($collection)
{
$data = new $collection(['michael', 'tom']);

$data = $data->when->contains('michael')->concat(['chris']);

$this->assertSame(['michael', 'tom', 'chris'], $data->toArray());

$data = $data->when->contains('missing')->concat(['adam']);

$this->assertSame(['michael', 'tom', 'chris'], $data->toArray());

$data = $data->unless->contains('missing')->concat(['adam']);

$this->assertSame(['michael', 'tom', 'chris', 'adam'], $data->toArray());

$data = $data->unless->contains('adam')->concat(['bogdan']);

$this->assertSame(['michael', 'tom', 'chris', 'adam'], $data->toArray());
}

/**
* @dataProvider collectionClassProvider
*/
Expand Down
93 changes: 89 additions & 4 deletions tests/Support/SupportConditionableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,68 +9,148 @@ class SupportConditionableTest extends TestCase
{
public function testWhenConditionCallback()
{
// With static condition
$logger = (new ConditionableLogger())
->when(2, function ($logger, $condition) {
$logger->log('when', $condition);
}, function () {
}, function ($logger, $condition) {
$logger->log('default', $condition);
});

$this->assertSame(['when', 2], $logger->values);

// With callback condition
$logger = (new ConditionableLogger())->log('init')
->when(function ($logger) {
return $logger->has('init');
}, function ($logger, $condition) {
$logger->log('when', $condition);
}, function ($logger, $condition) {
$logger->log('default', $condition);
});

$this->assertSame(['init', 'when', true], $logger->values);
}

public function testWhenDefaultCallback()
{
// With static condition
$logger = (new ConditionableLogger())
->when(null, function () {
->when(null, function ($logger, $condition) {
$logger->log('when', $condition);
}, function ($logger, $condition) {
$logger->log('default', $condition);
});

$this->assertSame(['default', null], $logger->values);

// With callback condition
$logger = (new ConditionableLogger())
->when(function ($logger) {
return $logger->has('missing');
}, function ($logger, $condition) {
$logger->log('when', $condition);
}, function ($logger, $condition) {
$logger->log('default', $condition);
});

$this->assertSame(['default', false], $logger->values);
}

public function testUnlessConditionCallback()
{
// With static condition
$logger = (new ConditionableLogger())
->unless(null, function ($logger, $condition) {
$logger->log('unless', $condition);
}, function () {
}, function ($logger, $condition) {
$logger->log('default', $condition);
});

$this->assertSame(['unless', null], $logger->values);

// With callback condition
$logger = (new ConditionableLogger())
->unless(function ($logger) {
return $logger->has('missing');
}, function ($logger, $condition) {
$logger->log('unless', $condition);
}, function ($logger, $condition) {
$logger->log('default', $condition);
});

$this->assertSame(['unless', false], $logger->values);
}

public function testUnlessDefaultCallback()
{
// With static condition
$logger = (new ConditionableLogger())
->unless(2, function () {
->unless(2, function ($logger, $condition) {
$logger->log('unless', $condition);
}, function ($logger, $condition) {
$logger->log('default', $condition);
});

$this->assertSame(['default', 2], $logger->values);

// With callback condition
$logger = (new ConditionableLogger())->log('init')
->unless(function ($logger) {
return $logger->has('init');
}, function ($logger, $condition) {
$logger->log('unless', $condition);
}, function ($logger, $condition) {
$logger->log('default', $condition);
});

$this->assertSame(['init', 'default', true], $logger->values);
}

public function testWhenProxy()
{
// With static condition
$logger = (new ConditionableLogger())
->when(true)->log('one')
->when(false)->log('two');

$this->assertSame(['one'], $logger->values);

// With callback condition
$logger = (new ConditionableLogger())->log('init')
->when(function ($logger) {
return $logger->has('init');
})
->log('one')
->when(function ($logger) {
return $logger->has('missing');
})
->log('two');

$this->assertSame(['init', 'one'], $logger->values);
}

public function testUnlessProxy()
{
// With static condition
$logger = (new ConditionableLogger())
->unless(true)->log('one')
->unless(false)->log('two');

$this->assertSame(['two'], $logger->values);

// With callback condition
$logger = (new ConditionableLogger())->log('init')
->unless(function ($logger) {
return $logger->has('init');
})
->log('one')
->unless(function ($logger) {
return $logger->has('missing');
})
->log('two');

$this->assertSame(['init', 'two'], $logger->values);
}
}

Expand All @@ -86,4 +166,9 @@ public function log(...$values)

return $this;
}

public function has($value)
{
return in_array($value, $this->values);
}
}

0 comments on commit b7f0359

Please sign in to comment.