Subversion-Projekte lars-tiefland.laravel_shop

Revision

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