Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 621 | 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 {
1464 lars 97
                        $normalizedListener = [
98
                            $expectedListener,
99
                            method_exists($expectedListener, 'handle') ? 'handle' : '__invoke',
100
                        ];
148 lars 101
                    }
102
                }
103
            }
104
 
621 lars 105
            if ($actualListener === $normalizedListener ||
148 lars 106
                ($actualListener instanceof Closure &&
621 lars 107
                $normalizedListener === Closure::class)) {
148 lars 108
                PHPUnit::assertTrue(true);
109
 
110
                return;
111
            }
112
        }
113
 
114
        PHPUnit::assertTrue(
115
            false,
116
            sprintf(
117
                'Event [%s] does not have the [%s] listener attached to it',
118
                $expectedEvent,
119
                print_r($expectedListener, true)
120
            )
121
        );
122
    }
123
 
124
    /**
125
     * Assert if an event was dispatched based on a truth-test callback.
126
     *
127
     * @param  string|\Closure  $event
128
     * @param  callable|int|null  $callback
129
     * @return void
130
     */
131
    public function assertDispatched($event, $callback = null)
132
    {
133
        if ($event instanceof Closure) {
134
            [$event, $callback] = [$this->firstClosureParameterType($event), $event];
135
        }
136
 
137
        if (is_int($callback)) {
138
            return $this->assertDispatchedTimes($event, $callback);
139
        }
140
 
141
        PHPUnit::assertTrue(
142
            $this->dispatched($event, $callback)->count() > 0,
143
            "The expected [{$event}] event was not dispatched."
144
        );
145
    }
146
 
147
    /**
148
     * Assert if an event was dispatched a number of times.
149
     *
150
     * @param  string  $event
151
     * @param  int  $times
152
     * @return void
153
     */
154
    public function assertDispatchedTimes($event, $times = 1)
155
    {
156
        $count = $this->dispatched($event)->count();
157
 
158
        PHPUnit::assertSame(
159
            $times, $count,
160
            "The expected [{$event}] event was dispatched {$count} times instead of {$times} times."
161
        );
162
    }
163
 
164
    /**
165
     * Determine if an event was dispatched based on a truth-test callback.
166
     *
167
     * @param  string|\Closure  $event
168
     * @param  callable|null  $callback
169
     * @return void
170
     */
171
    public function assertNotDispatched($event, $callback = null)
172
    {
173
        if ($event instanceof Closure) {
174
            [$event, $callback] = [$this->firstClosureParameterType($event), $event];
175
        }
176
 
177
        PHPUnit::assertCount(
178
            0, $this->dispatched($event, $callback),
179
            "The unexpected [{$event}] event was dispatched."
180
        );
181
    }
182
 
183
    /**
184
     * Assert that no events were dispatched.
185
     *
186
     * @return void
187
     */
188
    public function assertNothingDispatched()
189
    {
190
        $count = count(Arr::flatten($this->events));
191
 
192
        PHPUnit::assertSame(
193
            0, $count,
194
            "{$count} unexpected events were dispatched."
195
        );
196
    }
197
 
198
    /**
199
     * Get all of the events matching a truth-test callback.
200
     *
201
     * @param  string  $event
202
     * @param  callable|null  $callback
203
     * @return \Illuminate\Support\Collection
204
     */
205
    public function dispatched($event, $callback = null)
206
    {
207
        if (! $this->hasDispatched($event)) {
208
            return collect();
209
        }
210
 
211
        $callback = $callback ?: fn () => true;
212
 
213
        return collect($this->events[$event])->filter(
214
            fn ($arguments) => $callback(...$arguments)
215
        );
216
    }
217
 
218
    /**
219
     * Determine if the given event has been dispatched.
220
     *
221
     * @param  string  $event
222
     * @return bool
223
     */
224
    public function hasDispatched($event)
225
    {
226
        return isset($this->events[$event]) && ! empty($this->events[$event]);
227
    }
228
 
229
    /**
230
     * Register an event listener with the dispatcher.
231
     *
232
     * @param  \Closure|string|array  $events
233
     * @param  mixed  $listener
234
     * @return void
235
     */
236
    public function listen($events, $listener = null)
237
    {
238
        $this->dispatcher->listen($events, $listener);
239
    }
240
 
241
    /**
242
     * Determine if a given event has listeners.
243
     *
244
     * @param  string  $eventName
245
     * @return bool
246
     */
247
    public function hasListeners($eventName)
248
    {
249
        return $this->dispatcher->hasListeners($eventName);
250
    }
251
 
252
    /**
253
     * Register an event and payload to be dispatched later.
254
     *
255
     * @param  string  $event
256
     * @param  array  $payload
257
     * @return void
258
     */
259
    public function push($event, $payload = [])
260
    {
261
        //
262
    }
263
 
264
    /**
265
     * Register an event subscriber with the dispatcher.
266
     *
267
     * @param  object|string  $subscriber
268
     * @return void
269
     */
270
    public function subscribe($subscriber)
271
    {
272
        $this->dispatcher->subscribe($subscriber);
273
    }
274
 
275
    /**
276
     * Flush a set of pushed events.
277
     *
278
     * @param  string  $event
279
     * @return void
280
     */
281
    public function flush($event)
282
    {
283
        //
284
    }
285
 
286
    /**
287
     * Fire an event and call the listeners.
288
     *
289
     * @param  string|object  $event
290
     * @param  mixed  $payload
291
     * @param  bool  $halt
292
     * @return array|null
293
     */
294
    public function dispatch($event, $payload = [], $halt = false)
295
    {
296
        $name = is_object($event) ? get_class($event) : (string) $event;
297
 
298
        if ($this->shouldFakeEvent($name, $payload)) {
299
            $this->events[$name][] = func_get_args();
300
        } else {
301
            return $this->dispatcher->dispatch($event, $payload, $halt);
302
        }
303
    }
304
 
305
    /**
306
     * Determine if an event should be faked or actually dispatched.
307
     *
308
     * @param  string  $eventName
309
     * @param  mixed  $payload
310
     * @return bool
311
     */
312
    protected function shouldFakeEvent($eventName, $payload)
313
    {
314
        if ($this->shouldDispatchEvent($eventName, $payload)) {
315
            return false;
316
        }
317
 
318
        if (empty($this->eventsToFake)) {
319
            return true;
320
        }
321
 
322
        return collect($this->eventsToFake)
323
            ->filter(function ($event) use ($eventName, $payload) {
324
                return $event instanceof Closure
325
                            ? $event($eventName, $payload)
326
                            : $event === $eventName;
327
            })
328
            ->isNotEmpty();
329
    }
330
 
331
    /**
332
     * Determine whether an event should be dispatched or not.
333
     *
334
     * @param  string  $eventName
335
     * @param  mixed  $payload
336
     * @return bool
337
     */
338
    protected function shouldDispatchEvent($eventName, $payload)
339
    {
340
        if (empty($this->eventsToDispatch)) {
341
            return false;
342
        }
343
 
344
        return collect($this->eventsToDispatch)
345
            ->filter(function ($event) use ($eventName, $payload) {
346
                return $event instanceof Closure
347
                    ? $event($eventName, $payload)
348
                    : $event === $eventName;
349
            })
350
            ->isNotEmpty();
351
    }
352
 
353
    /**
354
     * Remove a set of listeners from the dispatcher.
355
     *
356
     * @param  string  $event
357
     * @return void
358
     */
359
    public function forget($event)
360
    {
361
        //
362
    }
363
 
364
    /**
365
     * Forget all of the queued listeners.
366
     *
367
     * @return void
368
     */
369
    public function forgetPushed()
370
    {
371
        //
372
    }
373
 
374
    /**
375
     * Dispatch an event and call the listeners.
376
     *
377
     * @param  string|object  $event
378
     * @param  mixed  $payload
379
     * @return array|null
380
     */
381
    public function until($event, $payload = [])
382
    {
383
        return $this->dispatch($event, $payload, true);
384
    }
385
}