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\Exception\InvalidIsbnException;
13use AppDemo\Library\Domain\ISBN;
14use Tests\Phexium\Fake\Domain\StringValueObject as FakeValueObject;
15
16describe('Creation', function (): void {
17    it('creates an ISBN-13 using static factory method', function (): void {
18        $isbn = ISBN::fromString('9780134494166');
19
20        expect($isbn->getValue())->toBe('9780134494166')
21            ->and($isbn->jsonSerialize())->toBe('9780134494166')
22            ->and($isbn->getFormattedValue())->toBe('978-013-449416-6')
23            ->and((string) $isbn)->toBe('978-013-449416-6')
24        ;
25    });
26
27    it('normalizes by removing non-digit characters', function (): void {
28        $isbn = ISBN::fromString('978-0-13-449416-6');
29
30        expect($isbn->getValue())->toBe('9780134494166');
31    });
32
33    it('accepts valid ISBN-13 with checksum digit 10 becoming 0', function (): void {
34        $isbn = ISBN::fromString('9783161484100');
35
36        expect($isbn->getValue())->toBe('9783161484100');
37    });
38});
39
40describe('Equality', function (): void {
41    it('considers two ISBNs with same value as equal', function (): void {
42        $isbn1 = ISBN::fromString('9780134494166');
43        $isbn2 = ISBN::fromString('978-0-13-449416-6');
44
45        expect($isbn1->equals($isbn2))->toBeTrue();
46    });
47
48    it('considers two ISBNs with different values as not equal', function (): void {
49        $isbn1 = ISBN::fromString('9780134494166');
50        $isbn2 = ISBN::fromString('9781737519799');
51
52        expect($isbn1->equals($isbn2))->toBeFalse();
53    });
54
55    it('considers an ISBN and another value object as not equal', function (): void {
56        $isbn = ISBN::fromString('9780134494166');
57        $object = FakeValueObject::fromString('9780134494166');
58
59        expect($isbn->equals($object))->toBeFalse();
60    });
61});
62
63describe('Validation', function (): void {
64    it('throws exception for empty ISBN', function (): void {
65        expect(fn (): ISBN => ISBN::fromString(''))
66            ->toThrow(InvalidIsbnException::class, 'ISBN cannot be empty')
67        ;
68    });
69
70    it('throws exception for invalid ISBN-13', function (): void {
71        expect(fn (): ISBN => ISBN::fromString('1234567890123'))
72            ->toThrow(InvalidIsbnException::class, 'Invalid ISBN-13 checksum')
73        ;
74    });
75});