Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
48 / 48
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10pest()->group('unit');
11
12use AppDemo\Library\Domain\Author;
13use AppDemo\Library\Domain\Exception\InvalidAuthorException;
14use Tests\Phexium\Fake\Domain\StringValueObject as FakeValueObject;
15
16describe('Creation', function (): void {
17    it('creates author using static factory method', function (): void {
18        $author = Author::fromString('John Doe');
19
20        expect($author->getValue())->toBe('John Doe')
21            ->and($author->jsonSerialize())->toBe('John Doe')
22            ->and((string) $author)->toBe('John Doe')
23        ;
24    });
25
26    it('normalizes by trimming whitespace', function (): void {
27        $author = Author::fromString('  John Doe  ');
28
29        expect($author->getValue())->toBe('John Doe');
30    });
31});
32
33describe('Equality', function (): void {
34    it('considers two authors with same value as equal', function (): void {
35        $author1 = Author::fromString('John Doe');
36        $author2 = Author::fromString('John Doe ');
37
38        expect($author1->equals($author2))->toBeTrue();
39    });
40
41    it('considers two authors with different values as not equal', function (): void {
42        $author1 = Author::fromString('John Doe');
43        $author2 = Author::fromString('Jane Doe');
44
45        expect($author1->equals($author2))->toBeFalse();
46    });
47
48    it('considers an author and another value object as not equal', function (): void {
49        $author = Author::fromString('John Doe');
50        $object = FakeValueObject::fromString('John Doe');
51
52        expect($author->equals($object))->toBeFalse();
53    });
54});
55
56describe('Validation', function (): void {
57    it('throws exception for empty author', function (): void {
58        expect(fn (): Author => Author::fromString(''))
59            ->toThrow(InvalidAuthorException::class, 'Author cannot be empty')
60        ;
61    });
62
63    it('accepts author with exactly 100 characters', function (): void {
64        $author = Author::fromString(str_repeat('a', 100));
65
66        expect(strlen($author->getValue()))->toBe(100);
67    });
68
69    it('throws exception for author exceeding 100 characters', function (): void {
70        $longAuthor = str_repeat('a', 101);
71        expect(fn (): Author => Author::fromString($longAuthor))
72            ->toThrow(InvalidAuthorException::class, 'Author cannot exceed 100 characters')
73        ;
74    });
75});