Subversion-Projekte lars-tiefland.laravel_shop

Revision

Zur aktuellen Revision | Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Foundation\Testing;
4
 
5
use Carbon\CarbonImmutable;
6
use Illuminate\Console\Application as Artisan;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Foundation\Bootstrap\HandleExceptions;
9
use Illuminate\Queue\Queue;
10
use Illuminate\Support\Carbon;
11
use Illuminate\Support\Facades\Facade;
12
use Illuminate\Support\Facades\ParallelTesting;
13
use Illuminate\Support\Str;
14
use Illuminate\View\Component;
15
use Mockery;
16
use Mockery\Exception\InvalidCountException;
17
use PHPUnit\Framework\TestCase as BaseTestCase;
18
use PHPUnit\Util\Annotation\Registry;
19
use Throwable;
20
 
21
abstract class TestCase extends BaseTestCase
22
{
23
    use Concerns\InteractsWithContainer,
24
        Concerns\MakesHttpRequests,
25
        Concerns\InteractsWithAuthentication,
26
        Concerns\InteractsWithConsole,
27
        Concerns\InteractsWithDatabase,
28
        Concerns\InteractsWithDeprecationHandling,
29
        Concerns\InteractsWithExceptionHandling,
30
        Concerns\InteractsWithSession,
31
        Concerns\InteractsWithTime,
32
        Concerns\InteractsWithViews,
33
        Concerns\MocksApplicationServices;
34
 
35
    /**
36
     * The Illuminate application instance.
37
     *
38
     * @var \Illuminate\Foundation\Application
39
     */
40
    protected $app;
41
 
42
    /**
43
     * The callbacks that should be run after the application is created.
44
     *
45
     * @var array
46
     */
47
    protected $afterApplicationCreatedCallbacks = [];
48
 
49
    /**
50
     * The callbacks that should be run before the application is destroyed.
51
     *
52
     * @var array
53
     */
54
    protected $beforeApplicationDestroyedCallbacks = [];
55
 
56
    /**
57
     * The exception thrown while running an application destruction callback.
58
     *
59
     * @var \Throwable
60
     */
61
    protected $callbackException;
62
 
63
    /**
64
     * Indicates if we have made it through the base setUp function.
65
     *
66
     * @var bool
67
     */
68
    protected $setUpHasRun = false;
69
 
70
    /**
71
     * Creates the application.
72
     *
73
     * Needs to be implemented by subclasses.
74
     *
75
     * @return \Symfony\Component\HttpKernel\HttpKernelInterface
76
     */
77
    abstract public function createApplication();
78
 
79
    /**
80
     * Setup the test environment.
81
     *
82
     * @return void
83
     */
84
    protected function setUp(): void
85
    {
86
        static::$latestResponse = null;
87
 
88
        Facade::clearResolvedInstances();
89
 
90
        if (! $this->app) {
91
            $this->refreshApplication();
92
 
93
            ParallelTesting::callSetUpTestCaseCallbacks($this);
94
        }
95
 
96
        $this->setUpTraits();
97
 
98
        foreach ($this->afterApplicationCreatedCallbacks as $callback) {
99
            $callback();
100
        }
101
 
102
        Model::setEventDispatcher($this->app['events']);
103
 
104
        $this->setUpHasRun = true;
105
    }
106
 
107
    /**
108
     * Refresh the application instance.
109
     *
110
     * @return void
111
     */
112
    protected function refreshApplication()
113
    {
114
        $this->app = $this->createApplication();
115
    }
116
 
117
    /**
118
     * Boot the testing helper traits.
119
     *
120
     * @return array
121
     */
122
    protected function setUpTraits()
123
    {
124
        $uses = array_flip(class_uses_recursive(static::class));
125
 
126
        if (isset($uses[RefreshDatabase::class])) {
127
            $this->refreshDatabase();
128
        }
129
 
130
        if (isset($uses[DatabaseMigrations::class])) {
131
            $this->runDatabaseMigrations();
132
        }
133
 
134
        if (isset($uses[DatabaseTransactions::class])) {
135
            $this->beginDatabaseTransaction();
136
        }
137
 
138
        if (isset($uses[WithoutMiddleware::class])) {
139
            $this->disableMiddlewareForAllTests();
140
        }
141
 
142
        if (isset($uses[WithoutEvents::class])) {
143
            $this->disableEventsForAllTests();
144
        }
145
 
146
        if (isset($uses[WithFaker::class])) {
147
            $this->setUpFaker();
148
        }
149
 
150
        foreach ($uses as $trait) {
151
            if (method_exists($this, $method = 'setUp'.class_basename($trait))) {
152
                $this->{$method}();
153
            }
154
 
155
            if (method_exists($this, $method = 'tearDown'.class_basename($trait))) {
156
                $this->beforeApplicationDestroyed(fn () => $this->{$method}());
157
            }
158
        }
159
 
160
        return $uses;
161
    }
162
 
163
    /**
164
     * Clean up the testing environment before the next test.
165
     *
166
     * @return void
167
     *
168
     * @throws \Mockery\Exception\InvalidCountException
169
     */
170
    protected function tearDown(): void
171
    {
172
        if ($this->app) {
173
            $this->callBeforeApplicationDestroyedCallbacks();
174
 
175
            ParallelTesting::callTearDownTestCaseCallbacks($this);
176
 
177
            $this->app->flush();
178
 
179
            $this->app = null;
180
        }
181
 
182
        $this->setUpHasRun = false;
183
 
184
        if (property_exists($this, 'serverVariables')) {
185
            $this->serverVariables = [];
186
        }
187
 
188
        if (property_exists($this, 'defaultHeaders')) {
189
            $this->defaultHeaders = [];
190
        }
191
 
192
        if (class_exists('Mockery')) {
193
            if ($container = Mockery::getContainer()) {
194
                $this->addToAssertionCount($container->mockery_getExpectationCount());
195
            }
196
 
197
            try {
198
                Mockery::close();
199
            } catch (InvalidCountException $e) {
200
                if (! Str::contains($e->getMethodName(), ['doWrite', 'askQuestion'])) {
201
                    throw $e;
202
                }
203
            }
204
        }
205
 
206
        if (class_exists(Carbon::class)) {
207
            Carbon::setTestNow();
208
        }
209
 
210
        if (class_exists(CarbonImmutable::class)) {
211
            CarbonImmutable::setTestNow();
212
        }
213
 
214
        $this->afterApplicationCreatedCallbacks = [];
215
        $this->beforeApplicationDestroyedCallbacks = [];
216
 
217
        $this->originalExceptionHandler = null;
218
        $this->originalDeprecationHandler = null;
219
 
220
        Artisan::forgetBootstrappers();
221
        Component::flushCache();
222
        Component::forgetComponentsResolver();
223
        Component::forgetFactory();
224
        Queue::createPayloadUsing(null);
225
        HandleExceptions::forgetApp();
226
 
227
        if ($this->callbackException) {
228
            throw $this->callbackException;
229
        }
230
    }
231
 
232
    /**
233
     * Clean up the testing environment before the next test case.
234
     *
235
     * @return void
236
     */
237
    public static function tearDownAfterClass(): void
238
    {
239
        static::$latestResponse = null;
240
 
241
        (function () {
242
            $this->classDocBlocks = [];
243
            $this->methodDocBlocks = [];
244
        })->call(Registry::getInstance());
245
    }
246
 
247
    /**
248
     * Register a callback to be run after the application is created.
249
     *
250
     * @param  callable  $callback
251
     * @return void
252
     */
253
    public function afterApplicationCreated(callable $callback)
254
    {
255
        $this->afterApplicationCreatedCallbacks[] = $callback;
256
 
257
        if ($this->setUpHasRun) {
258
            $callback();
259
        }
260
    }
261
 
262
    /**
263
     * Register a callback to be run before the application is destroyed.
264
     *
265
     * @param  callable  $callback
266
     * @return void
267
     */
268
    protected function beforeApplicationDestroyed(callable $callback)
269
    {
270
        $this->beforeApplicationDestroyedCallbacks[] = $callback;
271
    }
272
 
273
    /**
274
     * Execute the application's pre-destruction callbacks.
275
     *
276
     * @return void
277
     */
278
    protected function callBeforeApplicationDestroyedCallbacks()
279
    {
280
        foreach ($this->beforeApplicationDestroyedCallbacks as $callback) {
281
            try {
282
                $callback();
283
            } catch (Throwable $e) {
284
                if (! $this->callbackException) {
285
                    $this->callbackException = $e;
286
                }
287
            }
288
        }
289
    }
290
 
291
    /**
292
     * This method is called when a test method did not execute successfully.
293
     *
294
     * @param  \Throwable  $exception
295
     * @return void
296
     */
297
    protected function onNotSuccessfulTest(Throwable $exception): void
298
    {
299
        parent::onNotSuccessfulTest(
300
            is_null(static::$latestResponse)
301
                ? $exception
302
                : static::$latestResponse->transformNotSuccessfulException($exception)
303
        );
304
    }
305
}