Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Zur aktuellen Revision | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Support\Testing\Fakes;
4
 
5
use Closure;
6
use Illuminate\Contracts\Events\Dispatcher;
7
use Illuminate\Support\Arr;
8
use Illuminate\Support\Str;
9
use Illuminate\Support\Traits\ReflectsClosures;
10
use PHPUnit\Framework\Assert as PHPUnit;
11
use ReflectionFunction;
12
 
13
class EventFake implements Dispatcher
14
{
15
    use ReflectsClosures;
16
 
17
    /**
18
     * The original event dispatcher.
19
     *
20
     * @var \Illuminate\Contracts\Events\Dispatcher
21
     */
22
    protected $dispatcher;
23
 
24
    /**
25
     * The event types that should be intercepted instead of dispatched.
26
     *
27
     * @var array
28
     */
29
    protected $eventsToFake = [];
30
 
31
    /**
32
     * The event types that should be dispatched instead of intercepted.
33
     *
34
     * @var array
35
     */
36
    protected $eventsToDispatch = [];
37
 
38
    /**
39
     * All of the events that have been intercepted keyed by type.
40
     *
41
     * @var array
42
     */
43
    protected $events = [];
44
 
45
    /**
46
     * Create a new event fake instance.
47
     *
48
     * @param  \Illuminate\Contracts\Events\Dispatcher  $dispatcher
49
     * @param  array|string  $eventsToFake
50
     * @return void
51
     */
52
    public function __construct(Dispatcher $dispatcher, $eventsToFake = [])
53
    {
54
        $this->dispatcher = $dispatcher;
55
 
56
        $this->eventsToFake = Arr::wrap($eventsToFake);
57
    }
58
 
59
    /**
60
     * Specify the events that should be dispatched instead of faked.
61
     *
62
     * @param  array|string  $eventsToDispatch
63
     * @return $this
64
     */
65
    public function except($eventsToDispatch)
66
    {
67
        $this->eventsToDispatch = array_merge(
68
            $this->eventsToDispatch,
69
            Arr::wrap($eventsToDispatch)
70
        );
71
 
72
        return $this;
73
    }
74
 
75
    /**
76
     * Assert if an event has a listener attached to it.
77
     *
78
     * @param  string  $expectedEvent
79
     * @param  string|array  $expectedListener
80
     * @return void
81
     */
82
    public function assertListening($expectedEvent, $expectedListener)
83
    {
84
        foreach ($this->dispatcher->getListeners($expectedEvent) as $listenerClosure) {
85
            $actualListener = (new ReflectionFunction($listenerClosure))
86
                        ->getStaticVariables()['listener'];
87
 
621 lars 88
            $normalizedListener = $expectedListener;
89
 
148 lars 90
            if (is_string($actualListener) && Str::contains($actualListener, '@')) {
91
                $actualListener = Str::parseCallback($actualListener);
92
 
93
                if (is_string($expectedListener)) {
94
                    if (Str::contains($expectedListener, '@')) {
621 lars 95
                        $normalizedListener = Str::parseCallback($expectedListener);
148 lars 96
                    } else {
621 lars 97
                        $normalizedListener = [$expectedListener, 'handle'];
148 lars 98
                    }
99
                }
100
            }
101
 
621 lars 102
            if ($actualListener === $normalizedListener ||
148 lars 103
                ($actualListener instanceof Closure &&
621 lars 104
                $normalizedListener === Closure::class)) {
148 lars 105
                PHPUnit::assertTrue(true);
106
 
107
                return;
108
            }
109
        }
110
 
111
        PHPUnit::assertTrue(
112
            false,
113
            sprintf(
114
                'Event [%s] does not have the [%s] listener attached to it',
115
                $expectedEvent,
116
                print_r($expectedListener, true)
117
            )
118
        );
119
    }
120
 
121
    /**
122
     * Assert if an event was dispatched based on a truth-test callback.
123
     *
124
     * @param  string|\Closure  $event
125
     * @param  callable|int|null  $callback
126
     * @return void
127
     */
128
    public function assertDispatched($event, $callback = null)
129
    {
130
        if ($event instanceof Closure) {
131
            [$event, $callback] = [$this->firstClosureParameterType($event), $event];
132
        }
133
 
134
        if (is_int($callback)) {
135
            return $this->assertDispatchedTimes($event, $callback);
136
        }
137
 
138
        PHPUnit::assertTrue(
139
            $this->dispatched($event, $callback)->count() > 0,
140
            "The expected [{$event}] event was not dispatched."
141
        );
142
    }
143
 
144
    /**
145
     * Assert if an event was dispatched a number of times.
146
     *
147
     * @param  string  $event
148
     * @param  int  $times
149
     * @return void
150
     */
151
    public function assertDispatchedTimes($event, $times = 1)
152
    {
153
        $count = $this->dispatched($event)->count();
154
 
155
        PHPUnit::assertSame(
156
            $times, $count,
157
            "The expected [{$event}] event was dispatched {$count} times instead of {$times} times."
158
        );
159
    }
160
 
161
    /**
162
     * Determine if an event was dispatched based on a truth-test callback.
163
     *
164
     * @param  string|\Closure  $event
165
     * @param  callable|null  $callback
166
     * @return void
167
     */
168
    public function assertNotDispatched($event, $callback = null)
169
    {
170
        if ($event instanceof Closure) {
171
            [$event, $callback] = [$this->firstClosureParameterType($event), $event];
172
        }
173
 
174
        PHPUnit::assertCount(
175
            0, $this->dispatched($event, $callback),
176
            "The unexpected [{$event}] event was dispatched."
177
        );
178
    }
179
 
180
    /**
181
     * Assert that no events were dispatched.
182
     *
183
     * @return void
184
     */
185
    public function assertNothingDispatched()
186
    {
187
        $count = count(Arr::flatten($this->events));
188
 
189
        PHPUnit::assertSame(
190
            0, $count,
191
            "{$count} unexpected events were dispatched."
192
        );
193
    }
194
 
195
    /**
196
     * Get all of the events matching a truth-test callback.
197
     *
198
     * @param  string  $event
199
     * @param  callable|null  $callback
200
     * @return \Illuminate\Support\Collection
201
     */
202
    public function dispatched($event, $callback = null)
203
    {
204
        if (! $this->hasDispatched($event)) {
205
            return collect();
206
        }
207
 
208
        $callback = $callback ?: fn () => true;
209
 
210
        return collect($this->events[$event])->filter(
211
            fn ($arguments) => $callback(...$arguments)
212
        );
213
    }
214
 
215
    /**
216
     * Determine if the given event has been dispatched.
217
     *
218
     * @param  string  $event
219
     * @return bool
220
     */
221
    public function hasDispatched($event)
222
    {
223
        return isset($this->events[$event]) && ! empty($this->events[$event]);
224
    }
225
 
226
    /**
227
     * Register an event listener with the dispatcher.
228
     *
229
     * @param  \Closure|string|array  $events
230
     * @param  mixed  $listener
231
     * @return void
232
     */
233
    public function listen($events, $listener = null)
234
    {
235
        $this->dispatcher->listen($events, $listener);
236
    }
237
 
238
    /**
239
     * Determine if a given event has listeners.
240
     *
241
     * @param  string  $eventName
242
     * @return bool
243
     */
244
    public function hasListeners($eventName)
245
    {
246
        return $this->dispatcher->hasListeners($eventName);
247
    }
248
 
249
    /**
250
     * Register an event and payload to be dispatched later.
251
     *
252
     * @param  string  $event
253
     * @param  array  $payload
254
     * @return void
255
     */
256
    public function push($event, $payload = [])
257
    {
258
        //
259
    }
260
 
261
    /**
262
     * Register an event subscriber with the dispatcher.
263
     *
264
     * @param  object|string  $subscriber
265
     * @return void
266
     */
267
    public function subscribe($subscriber)
268
    {
269
        $this->dispatcher->subscribe($subscriber);
270
    }
271
 
272
    /**
273
     * Flush a set of pushed events.
274
     *
275
     * @param  string  $event
276
     * @return void
277
     */
278
    public function flush($event)
279
    {
280
        //
281
    }
282
 
283
    /**
284
     * Fire an event and call the listeners.
285
     *
286
     * @param  string|object  $event
287
     * @param  mixed  $payload
288
     * @param  bool  $halt
289
     * @return array|null
290
     */
291
    public function dispatch($event, $payload = [], $halt = false)
292
    {
293
        $name = is_object($event) ? get_class($event) : (string) $event;
294
 
295
        if ($this->shouldFakeEvent($name, $payload)) {
296
            $this->events[$name][] = func_get_args();
297
        } else {
298
            return $this->dispatcher->dispatch($event, $payload, $halt);
299
        }
300
    }
301
 
302
    /**
303
     * Determine if an event should be faked or actually dispatched.
304
     *
305
     * @param  string  $eventName
306
     * @param  mixed  $payload
307
     * @return bool
308
     */
309
    protected function shouldFakeEvent($eventName, $payload)
310
    {
311
        if ($this->shouldDispatchEvent($eventName, $payload)) {
312
            return false;
313
        }
314
 
315
        if (empty($this->eventsToFake)) {
316
            return true;
317
        }
318
 
319
        return collect($this->eventsToFake)
320
            ->filter(function ($event) use ($eventName, $payload) {
321
                return $event instanceof Closure
322
                            ? $event($eventName, $payload)
323
                            : $event === $eventName;
324
            })
325
            ->isNotEmpty();
326
    }
327
 
328
    /**
329
     * Determine whether an event should be dispatched or not.
330
     *
331
     * @param  string  $eventName
332
     * @param  mixed  $payload
333
     * @return bool
334
     */
335
    protected function shouldDispatchEvent($eventName, $payload)
336
    {
337
        if (empty($this->eventsToDispatch)) {
338
            return false;
339
        }
340
 
341
        return collect($this->eventsToDispatch)
342
            ->filter(function ($event) use ($eventName, $payload) {
343
                return $event instanceof Closure
344
                    ? $event($eventName, $payload)
345
                    : $event === $eventName;
346
            })
347
            ->isNotEmpty();
348
    }
349
 
350
    /**
351
     * Remove a set of listeners from the dispatcher.
352
     *
353
     * @param  string  $event
354
     * @return void
355
     */
356
    public function forget($event)
357
    {
358
        //
359
    }
360
 
361
    /**
362
     * Forget all of the queued listeners.
363
     *
364
     * @return void
365
     */
366
    public function forgetPushed()
367
    {
368
        //
369
    }
370
 
371
    /**
372
     * Dispatch an event and call the listeners.
373
     *
374
     * @param  string|object  $event
375
     * @param  mixed  $payload
376
     * @return array|null
377
     */
378
    public function until($event, $payload = [])
379
    {
380
        return $this->dispatch($event, $payload, true);
381
    }
382
}