Passed
Pull Request — master (#84)
by Frank
02:06
created

MessageConsumerTestCase::ensureEventsAreMessages()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

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