Passed
Push — master ( cbefbc...3619f4 )
by Frank
16:49 queued 06:49
created

MessageConsumerTestCase::when()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 9
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EventSauce\EventSourcing\TestUtilities;
6
7
use EventSauce\EventSourcing\Message;
8
use EventSauce\EventSourcing\MessageConsumer;
9
use Exception;
10
use PHPUnit\Framework\TestCase;
11
12
abstract class MessageConsumerTestCase extends TestCase
13
{
14
    protected MessageConsumer $messageConsumer;
15
    private ?Exception $caughtException = null;
16
    private ?Exception $theExpectedException = null;
17
    private bool $assertedScenario = false;
18
19
    /**
20
     * @var callable
21
     */
22
    private $assertionCallback;
23
24
    abstract public function messageConsumer(): MessageConsumer;
25
26
    /**
27
     * @before
28
     */
29
    public function setupMessageConsumer(): void
30
    {
31
        $this->messageConsumer = $this->messageConsumer();
32
        $this->assertedScenario = false;
33
    }
34
35
    /**
36
     * @before
37
     */
38
    public function unsetMessageConsumer(): void
39
    {
40
        unset($this->messageConsumer);
41
    }
42
43
    /**
44
     * @return $this
45
     */
46
    protected function given(object ...$eventsOrMessages)
47
    {
48
        $this->processMessages($eventsOrMessages);
49
50
        return $this;
51
    }
52
53
    /**
54
     * @return $this
55
     */
56
    public function when(object ...$eventsOrMessages)
57
    {
58
        try {
59
            $this->processMessages($eventsOrMessages);
60
        } catch (Exception $exception) {
61
            $this->caughtException = $exception;
62
        }
63
64
        return $this;
65
    }
66
67
    /**
68
     * @return $this
69
     */
70
    public function expectToFail(Exception $expectedException)
71
    {
72
        $this->theExpectedException = $expectedException;
73
74
        return $this;
75
    }
76
77
    /**
78
     * @param object[] $eventsOrMessages
79
     */
80
    protected function processMessages(array $eventsOrMessages): void
81
    {
82
        $messages = $this->ensureEventsAreMessages($eventsOrMessages);
83
84
        foreach ($messages as $message) {
85
            $this->messageConsumer->handle($message);
86
        }
87
    }
88
89
    /**
90
     * @return Message[]
91
     */
92
    private function ensureEventsAreMessages(array $events): array
93
    {
94
        return array_map(function (object $event) {
95
            return $event instanceof Message ? $event : new Message($event);
96
        }, $events);
97
    }
98
99
    /**
100
     * @after
101
     *
102
     * @throws Exception
103
     */
104
    protected function assertScenario(): void
105
    {
106
        // @codeCoverageIgnoreStart
107
        if ($this->assertedScenario) {
108
            return;
109
        }
110
        // @codeCoverageIgnoreEnd
111
112
        $this->assertedScenario = true;
113
114
        $this->assertExpectedException($this->theExpectedException, $this->caughtException);
115
116
        if (is_callable($this->assertionCallback)) {
117
            ($this->assertionCallback)($this->messageConsumer);
118
        }
119
    }
120
121
    /**
122
     * @return $this
123
     */
124
    public function then(callable $assertion)
125
    {
126
        $this->assertionCallback = $assertion;
127
128
        return $this;
129
    }
130
131
    private function assertExpectedException(
132
        Exception $expectedException = null,
133
        Exception $caughtException = null
134
    ): void {
135
        if (null !== $caughtException && (null === $expectedException || get_class($expectedException) !== get_class(
136
                    $caughtException
137
                ))) {
138
            throw $caughtException;
139
        }
140
141
        self::assertEquals([$expectedException], [$caughtException], '>> Exceptions are not equal.');
142
    }
143
}
144