Passed
Pull Request — master (#33)
by Melech
03:22
created

Exceptions::verify()   B

Complexity

Conditions 8
Paths 7

Size

Total Lines 36
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 16
c 1
b 0
f 0
nc 7
nop 1
dl 0
loc 36
rs 8.4444
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Test\Assert\Asserters;
15
16
use Throwable;
17
use Valkyrja\Test\Assert\Exceptions as Contract;
18
use Valkyrja\Test\Exceptions\AssertFailureException;
19
20
/**
21
 * Class Exceptions.
22
 *
23
 * @author Melech Mizrachi
24
 */
25
class Exceptions extends Asserter implements Contract
26
{
27
    /**
28
     * Whether an exception is expected to be thrown.
29
     */
30
    protected bool $expecting = false;
31
32
    /**
33
     * The expected class name.
34
     *
35
     * @var class-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
36
     */
37
    protected string $className;
38
39
    /**
40
     * The expected message.
41
     */
42
    protected string $message;
43
44
    /**
45
     * @inheritDoc
46
     */
47
    public static function getExpectedErrorMessage(): string
48
    {
49
        return 'An exception was expected. Got none.';
50
    }
51
52
    /**
53
     * @inheritDoc
54
     */
55
    public static function getUnexpectedErrorMessage(string $actualClassName, string $actualMessage): string
56
    {
57
        return "An unexpected exception {$actualClassName} with message {$actualMessage} was thrown.";
58
    }
59
60
    /**
61
     * @inheritDoc
62
     */
63
    public static function getIncorrectClassNameErrorMessage(string $expected, string $actual): string
64
    {
65
        return "Expected {$expected} exception does not match actual {$actual}.";
66
    }
67
68
    /**
69
     * @inheritDoc
70
     */
71
    public static function getIncorrectMessageErrorMessage(string $expected, string $actual): string
72
    {
73
        return "Expected {$expected} message does not match actual {$actual}.";
74
    }
75
76
    /**
77
     * @inheritDoc
78
     */
79
    public function className(string $className): void
80
    {
81
        $this->assertions[] = $className;
82
83
        $this->className = $className;
84
85
        $this->expecting();
86
    }
87
88
    /**
89
     * @inheritDoc
90
     */
91
    public function message(string $message): void
92
    {
93
        $this->assertions[] = $message;
94
95
        $this->message = $message;
96
97
        $this->expecting();
98
    }
99
100
    /**
101
     * @inheritDoc
102
     */
103
    public function expecting(): void
104
    {
105
        $this->expecting = true;
106
    }
107
108
    /**
109
     * @inheritDoc
110
     */
111
    public function verify(Throwable $exception = null): void
112
    {
113
        if ($exception === null) {
114
            if ($this->expecting) {
115
                $this->errors[] = new AssertFailureException(self::getExpectedErrorMessage());
116
            }
117
118
            return;
119
        }
120
121
        $actualClassName = $exception::class;
122
        $actualMessage   = $exception->getMessage();
123
124
        if (! $this->expecting) {
125
            $this->errors[] = new AssertFailureException(
126
                self::getUnexpectedErrorMessage($actualClassName, $actualMessage)
127
            );
128
129
            return;
130
        }
131
132
        /**
133
         * @psalm-suppress RedundantConditionGivenDocblockType
134
         */
135
        if (isset($this->className) && ($className = $this->className) !== $actualClassName) {
136
            $this->errors[] = new AssertFailureException(
137
                self::getIncorrectClassNameErrorMessage($className, $actualClassName)
138
            );
139
        }
140
141
        /**
142
         * @psalm-suppress RedundantCondition
143
         */
144
        if (isset($this->message) && ($message = $this->message) !== $actualMessage) {
145
            $this->errors[] = new AssertFailureException(
146
                self::getIncorrectMessageErrorMessage($message, $actualMessage)
147
            );
148
        }
149
    }
150
}
151