Passed
Pull Request — master (#84)
by Frank
04:08
created

MessageConsumerTestCase::processMessages()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 6
ccs 4
cts 4
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
     * @before
51
     */
52 4
    public function unsetMessageConsumer(): void
53
    {
54 4
        unset($this->messageConsumer);
55 4
    }
56
57
    /**
58
     * @return $this
59
     */
60 1
    protected function given(... $eventsOrMessages)
61
    {
62 1
        $this->processMessages($eventsOrMessages);
63
64 1
        return $this;
65
    }
66
67
    /**
68
     * @return $this
69
     */
70 4
    public function when(... $eventsOrMessages)
71
    {
72
        try {
73 4
            $this->processMessages($eventsOrMessages);
74 3
        } catch (Exception $exception) {
75 3
            $this->caughtException = $exception;
76
        }
77
78 4
        return $this;
79
    }
80
81
    /**
82
     * @return $this
83
     */
84 2
    public function expectToFail(Exception $expectedException)
85
    {
86 2
        $this->theExpectedException = $expectedException;
87
88 2
        return $this;
89
    }
90
91
    /**
92
     * @param array $eventsOrMessages
93
     */
94 4
    protected function processMessages(array $eventsOrMessages): void
95
    {
96 4
        $messages = $this->ensureEventsAreMessages($eventsOrMessages);
97
98 4
        foreach ($messages as $message) {
99 4
            $this->messageConsumer->handle($message);
100
        }
101 2
    }
102
103
    /**
104
     * @return Message[]
105
     */
106 4
    private function ensureEventsAreMessages(array $events): array
107
    {
108
        return array_map(function(object $event) {
109 4
            return $event instanceof Message ? $event : new Message($event);
110 4
        }, $events);
111
    }
112
113
    /**
114
     * @after
115
     * @throws Exception
116
     */
117 4
    protected function assertScenario(): void
118
    {
119
        // @codeCoverageIgnoreStart
120
        if ($this->assertedScenario) {
121
            return;
122
        }
123
        // @codeCoverageIgnoreEnd
124
125 4
        $this->assertedScenario = true;
126
127 4
        $this->assertExpectedException($this->theExpectedException, $this->caughtException);
128
129 2
        if (is_callable($this->assertionCallback)) {
130 1
            ($this->assertionCallback)($this->messageConsumer);
131
        }
132 2
    }
133
134
    /**
135
     * @return $this
136
     */
137 1
    public function then(callable $assertion)
138
    {
139 1
        $this->assertionCallback = $assertion;
140
141 1
        return $this;
142
    }
143
144 4
    private function assertExpectedException(
145
        Exception $expectedException = null,
146
        Exception $caughtException = null
147
    ): void {
148 4
        if (null !== $caughtException && (null === $expectedException || get_class($expectedException) !== get_class(
149 4
                    $caughtException
150
                ))) {
151 2
            throw $caughtException;
152
        }
153
154 2
        self::assertEquals([$expectedException], [$caughtException], '>> Exceptions are not equal.');
155 2
    }
156
}
157