Skip to content

Commit 00aa6ea

Browse files
authored
feat(support): improve types of HasConditions (#800)
1 parent 15dd7bd commit 00aa6ea

File tree

10 files changed

+164
-17
lines changed

10 files changed

+164
-17
lines changed

src/Tempest/Console/src/Console.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,17 @@ public function error(string $line): self;
5656

5757
public function success(string $line): self;
5858

59-
public function when(mixed $expression, callable $callback): self;
59+
/**
60+
* @param mixed|Closure(self): bool $condition
61+
* @param Closure(self): self $callback
62+
*/
63+
public function when(mixed $condition, Closure $callback): self;
64+
65+
/**
66+
* @param mixed|Closure(self): bool $condition
67+
* @param Closure(self): self $callback
68+
*/
69+
public function unless(mixed $condition, Closure $callback): self;
6070

6171
public function withLabel(string $label): self;
6272

src/Tempest/Console/src/Exceptions/ConsoleErrorHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function handleException(Throwable $throwable): void
3434
->writeln()
3535
->error($throwable::class)
3636
->when(
37-
expression: $throwable->getMessage(),
37+
condition: $throwable->getMessage(),
3838
callback: fn (Console $console) => $console->error($throwable->getMessage()),
3939
)
4040
->writeln($this->getSnippet($throwable->getFile(), $throwable->getLine()))

src/Tempest/Console/src/GenericConsole.php

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@
2020
use Tempest\Container\Tag;
2121
use Tempest\Highlight\Highlighter;
2222
use Tempest\Highlight\Language;
23+
use Tempest\Support\Conditions\HasConditions;
2324

2425
final class GenericConsole implements Console
2526
{
27+
use HasConditions;
28+
2629
private ?string $label = null;
2730

2831
private bool $isForced = false;
@@ -149,15 +152,6 @@ public function withLabel(string $label): self
149152
return $clone;
150153
}
151154

152-
public function when(mixed $expression, callable $callback): self
153-
{
154-
if ($expression) {
155-
$callback($this);
156-
}
157-
158-
return $this;
159-
}
160-
161155
public function component(InteractiveConsoleComponent $component, array $validation = []): mixed
162156
{
163157
if ($this->supportsTty()) {

src/Tempest/Console/src/Middleware/OverviewMiddleware.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ private function renderOverview(bool $showHidden = false): void
6666
}
6767

6868
$this->console
69-
->when(
70-
expression: ! $this->discoveryCache->isValid(),
69+
->unless(
70+
condition: $this->discoveryCache->isValid(),
7171
callback: fn (Console $console) => $console->writeln(PHP_EOL . '<error>Discovery cache invalid. Run discovery:generate to enable discovery caching.</error>')
7272
);
7373
}

src/Tempest/Core/src/Commands/DiscoveryStatusCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ public function __invoke(): void
4242
$this->console
4343
->writeln()
4444
->when($this->discoveryCache->isEnabled(), fn (Console $console) => $console->success('Discovery cache enabled'))
45-
->when(! $this->discoveryCache->isEnabled(), fn (Console $console) => $console->error('Discovery cache disabled'));
45+
->unless($this->discoveryCache->isEnabled(), fn (Console $console) => $console->error('Discovery cache disabled'));
4646
}
4747
}

src/Tempest/Support/src/ArrayHelper.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Serializable;
1515
use Stringable;
1616
use function Tempest\map;
17+
use Tempest\Support\Conditions\HasConditions;
1718

1819
/**
1920
* @template TKey of array-key
@@ -25,6 +26,7 @@
2526
final class ArrayHelper implements Iterator, ArrayAccess, Serializable, Countable
2627
{
2728
use IsIterable;
29+
use HasConditions;
2830

2931
/** @var array<TKey, TValue> */
3032
private array $array;

src/Tempest/Support/src/Conditions/HasConditions.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,41 @@
44

55
namespace Tempest\Support\Conditions;
66

7+
use Closure;
8+
79
trait HasConditions
810
{
911
/**
12+
* Applies the given `$callback` if the `$condition` is true.
1013
*
11-
* @return $this
14+
* @param mixed|Closure(static): bool $condition
15+
* @param Closure(static): static $callback
1216
*/
13-
public function when(bool $condition, callable $callback): self
17+
public function when(mixed $condition, Closure $callback): static
1418
{
19+
if ($condition instanceof Closure) {
20+
$condition = $condition($this);
21+
}
22+
1523
if ($condition) {
1624
$callback($this);
1725
}
1826

1927
return $this;
2028
}
2129

22-
public function unless(bool $condition, callable $callback): self
30+
/**
31+
* Applies the given `$callback` if the `$condition` is false.
32+
*
33+
* @param mixed|Closure(static): bool $condition
34+
* @param Closure(static): static $callback
35+
*/
36+
public function unless(mixed $condition, Closure $callback): static
2337
{
38+
if ($condition instanceof Closure) {
39+
$condition = $condition($this);
40+
}
41+
2442
return $this->when(! $condition, $callback);
2543
}
2644
}

src/Tempest/Support/src/StringHelper.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@
44

55
namespace Tempest\Support;
66

7+
use Closure;
78
use Countable;
89
use function ltrim;
910
use function preg_quote;
1011
use function preg_replace;
1112
use function rtrim;
1213
use Stringable;
14+
use Tempest\Support\Conditions\HasConditions;
1315
use function trim;
1416

1517
final readonly class StringHelper implements Stringable
1618
{
19+
use HasConditions;
20+
1721
private string $string;
1822

1923
public function __construct(Stringable|string|null $string = '')
@@ -773,6 +777,21 @@ public function insertAt(int $position, string $string): self
773777
);
774778
}
775779

780+
public function when(mixed $condition, Closure $callback): static
781+
{
782+
if ($condition instanceof Closure) {
783+
$condition = $condition($this);
784+
}
785+
786+
if ($condition) {
787+
if (($result = $callback($this)) instanceof self) {
788+
return $result;
789+
}
790+
}
791+
792+
return $this;
793+
}
794+
776795
/**
777796
* Implodes the given array into a string by a separator.
778797
*/
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Support\Tests\Conditions;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Tempest\Support\Conditions\HasConditions;
9+
10+
/**
11+
* @internal
12+
*/
13+
final class HasConditionsTest extends TestCase
14+
{
15+
public function test_when(): void
16+
{
17+
$class = new class () {
18+
use HasConditions;
19+
20+
public bool $value = false;
21+
};
22+
23+
$class->when(true, fn ($c) => $c->value = true); // @phpstan-ignore-line
24+
25+
$this->assertTrue($class->value);
26+
}
27+
28+
public function test_when_with_callback(): void
29+
{
30+
$class = new class () {
31+
use HasConditions;
32+
33+
public bool $value = false;
34+
};
35+
36+
$class->when(fn () => true, fn ($c) => $c->value = true); // @phpstan-ignore-line
37+
38+
$this->assertTrue($class->value);
39+
}
40+
41+
public function test_unless(): void
42+
{
43+
$class = new class () {
44+
use HasConditions;
45+
46+
public bool $value = false;
47+
};
48+
49+
$class->unless(true, fn ($c) => $c->value = true); // @phpstan-ignore-line
50+
51+
$this->assertFalse($class->value);
52+
}
53+
54+
public function test_unless_with_callback(): void
55+
{
56+
$class = new class () {
57+
use HasConditions;
58+
59+
public bool $value = false;
60+
};
61+
62+
$class->unless(fn () => true, fn ($c) => $c->value = true); // @phpstan-ignore-line
63+
64+
$this->assertFalse($class->value);
65+
}
66+
67+
public function test_returns_same_instance(): void
68+
{
69+
$class = new class () {
70+
use HasConditions;
71+
72+
public string $string = 'foo';
73+
74+
public function append(string $string): static
75+
{
76+
$self = new self();
77+
$self->string = $this->string . $string;
78+
79+
return $self;
80+
}
81+
};
82+
83+
$class->when(true, function ($c): void { // @phpstan-ignore-line
84+
$c->append('bar');
85+
});
86+
87+
$this->assertSame('foo', $class->string);
88+
}
89+
}

src/Tempest/Support/tests/StringHelperTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,4 +557,19 @@ public function test_strip_tags(): void
557557
$this->assertSame('Hello <strong>World</strong>', str('<p>Hello <strong>World</strong></p>')->stripTags(allowed: 'strong')->toString());
558558
$this->assertSame('<p>Hello World</p>', str('<p>Hello <strong>World</strong></p>')->stripTags(allowed: 'p')->toString());
559559
}
560+
561+
public function test_when(): void
562+
{
563+
$this->assertTrue(str('foo')->when(true, fn ($s) => $s->append('bar'))->equals('foobar'));
564+
$this->assertTrue(str('foo')->when(false, fn ($s) => $s->append('bar'))->equals('foo'));
565+
566+
$this->assertTrue(str('foo')->when(fn () => true, fn ($s) => $s->append('bar'))->equals('foobar'));
567+
$this->assertTrue(str('foo')->when(fn () => false, fn ($s) => $s->append('bar'))->equals('foo'));
568+
569+
$this->assertTrue(str('foo')->when(fn ($s) => $s->startsWith('foo'), fn ($s) => $s->append('bar'))->equals('foobar'));
570+
$this->assertTrue(str('foo')->when(fn ($s) => $s->startsWith('bar'), fn ($s) => $s->append('bar'))->equals('foo'));
571+
572+
$this->assertTrue(str('foo')->when(true, fn ($s) => $s->append('bar'))->equals('foobar'));
573+
$this->assertTrue(str('foo')->when(false, fn ($s) => $s->append('bar'))->equals('foo'));
574+
}
560575
}

0 commit comments

Comments
 (0)