Skip to content

Commit d85eabe

Browse files
committed
feat: replace null return with NullImageBossBuilder null object pattern for safer chaining
1 parent 5e57764 commit d85eabe

File tree

4 files changed

+107
-7
lines changed

4 files changed

+107
-7
lines changed

src/Facades/ImageBoss.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use Statamic\Fields\Value;
99

1010
/**
11-
* @method static ?ImageBossBuilder from(Asset|Value|null $asset)
11+
* @method static ImageBossBuilder from(Asset|Value|null $asset)
1212
*
1313
* @see \Noo\StatamicImageboss\ImageBoss
1414
* @see ImageBossBuilder::url() For fixed-dimension URLs

src/ImageBoss.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77

88
class ImageBoss
99
{
10-
public function from(mixed $asset): ?ImageBossBuilder
10+
public function from(mixed $asset): ImageBossBuilder
1111
{
1212
if ($asset instanceof Value) {
1313
$asset = $asset->value();
1414
}
1515

1616
if ($asset === null) {
17-
return null;
17+
return new NullImageBossBuilder;
1818
}
1919

2020
if (! $asset instanceof Asset) {

src/NullImageBossBuilder.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
3+
namespace Noo\StatamicImageboss;
4+
5+
use Noo\StatamicImageboss\Contracts\ImagePreset;
6+
7+
class NullImageBossBuilder extends ImageBossBuilder
8+
{
9+
public function __construct()
10+
{
11+
}
12+
13+
public function width(?int $width): self
14+
{
15+
return $this;
16+
}
17+
18+
public function height(?int $height): self
19+
{
20+
return $this;
21+
}
22+
23+
public function ratio(?float $ratio): self
24+
{
25+
return $this;
26+
}
27+
28+
public function min(?int $min): self
29+
{
30+
return $this;
31+
}
32+
33+
public function max(?int $max): self
34+
{
35+
return $this;
36+
}
37+
38+
public function interval(?int $interval): self
39+
{
40+
return $this;
41+
}
42+
43+
public function preset(ImagePreset|\BackedEnum|string $preset): self
44+
{
45+
return $this;
46+
}
47+
48+
public function url(): string
49+
{
50+
return '';
51+
}
52+
53+
/**
54+
* @return array<int, array{url: string, width: int}>
55+
*/
56+
public function srcset(): array
57+
{
58+
return [];
59+
}
60+
61+
public function srcsetString(): string
62+
{
63+
return '';
64+
}
65+
66+
public function rias(): string
67+
{
68+
return '';
69+
}
70+
71+
public function aspectRatio(): ?float
72+
{
73+
return null;
74+
}
75+
}

tests/Feature/ImageBossBuilderTest.php

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use Noo\StatamicImageboss\ImageBoss;
44
use Noo\StatamicImageboss\ImageBossBuilder;
5+
use Noo\StatamicImageboss\NullImageBossBuilder;
56
use Noo\StatamicImageboss\Tests\Fixtures\InterfacePreset;
67
use Noo\StatamicImageboss\Tests\Fixtures\TestPreset;
78

@@ -301,17 +302,41 @@
301302
expect($builder->aspectRatio())->toBe(16 / 9);
302303
});
303304

304-
it('returns null from factory when asset is null', function () {
305+
it('returns NullImageBossBuilder from factory when asset is null', function () {
305306
$imageBoss = new ImageBoss;
306307

307-
expect($imageBoss->from(null))->toBeNull();
308+
$result = $imageBoss->from(null);
309+
310+
expect($result)->toBeInstanceOf(NullImageBossBuilder::class)
311+
->and($result->url())->toBe('');
308312
});
309313

310-
it('returns null from factory when Value unwraps to null', function () {
314+
it('returns NullImageBossBuilder from factory when Value unwraps to null', function () {
311315
$value = Mockery::mock(\Statamic\Fields\Value::class);
312316
$value->shouldReceive('value')->andReturn(null);
313317

314318
$imageBoss = new ImageBoss;
315319

316-
expect($imageBoss->from($value))->toBeNull();
320+
$result = $imageBoss->from($value);
321+
322+
expect($result)->toBeInstanceOf(NullImageBossBuilder::class)
323+
->and($result->url())->toBe('');
324+
});
325+
326+
it('returns empty values from null builder', function () {
327+
$builder = new NullImageBossBuilder;
328+
329+
expect($builder->url())->toBe('')
330+
->and($builder->srcset())->toBe([])
331+
->and($builder->srcsetString())->toBe('')
332+
->and($builder->rias())->toBe('')
333+
->and($builder->aspectRatio())->toBeNull();
334+
});
335+
336+
it('allows chaining on null builder', function () {
337+
$builder = new NullImageBossBuilder;
338+
339+
$result = $builder->width(800)->height(600)->ratio(16 / 9)->min(320)->max(2560)->interval(320)->url();
340+
341+
expect($result)->toBe('');
317342
});

0 commit comments

Comments
 (0)