• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

orchestral / testbench-core / 6661308521

27 Oct 2023 12:30AM UTC coverage: 92.024% (+0.09%) from 91.935%
6661308521

Pull #147

github

web-flow
Merge b3930202b into 3866f3aff
Pull Request #147: Add `Orchestra\Testbench\Concerns\ApplicationTestingHooks`

58 of 58 new or added lines in 3 files covered. (100.0%)

923 of 1003 relevant lines covered (92.02%)

40.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.91
/src/Concerns/ApplicationTestingHooks.php
1
<?php
2

3
namespace Orchestra\Testbench\Concerns;
4

5
use Carbon\Carbon;
6
use Carbon\CarbonImmutable;
7
use Closure;
8
use Illuminate\Console\Application as Artisan;
9
use Illuminate\Database\Eloquent\Model;
10
use Illuminate\Foundation\Bootstrap\HandleExceptions;
11
use Illuminate\Queue\Queue;
12
use Illuminate\Support\Facades\ParallelTesting;
13
use Illuminate\View\Component;
14
use Mockery;
15
use PHPUnit\Framework\TestCase;
16
use Throwable;
17

18
trait ApplicationTestingHooks
19
{
20
    /**
21
     * The Illuminate application instance.
22
     *
23
     * @var \Illuminate\Foundation\Application|null
24
     */
25
    protected $app;
26

27
    /**
28
     * The callbacks that should be run after the application is created.
29
     *
30
     * @var array<int, callable():void>
31
     */
32
    protected $afterApplicationCreatedCallbacks = [];
33

34
    /**
35
     * The callbacks that should be run after the application is refreshed.
36
     *
37
     * @var array<int, callable():void>
38
     */
39
    protected $afterApplicationRefreshedCallbacks = [];
40

41
    /**
42
     * The callbacks that should be run before the application is destroyed.
43
     *
44
     * @var array<int, callable():void>
45
     */
46
    protected $beforeApplicationDestroyedCallbacks = [];
47

48
    /**
49
     * The exception thrown while running an application destruction callback.
50
     *
51
     * @var \Throwable|null
52
     */
53
    protected $callbackException;
54

55
    /**
56
     * Setup the testing hooks.
57
     *
58
     * @param  (\Closure():(void))|null  $callback
59
     * @return void
60
     */
61
    final protected function setUpTheApplicationTestingHooks(?Closure $callback = null): void
62
    {
63
        if (! $this->app) {
100✔
64
            $this->refreshApplication();
100✔
65

66
            $this->setUpParallelTestingCallbacks();
100✔
67
        }
68

69
        /** @var \Illuminate\Foundation\Application $app */
70
        $app = $this->app;
100✔
71

72
        $this->callAfterApplicationRefreshedCallbacks();
100✔
73

74
        if (! \is_null($callback)) {
100✔
75
            \call_user_func($callback);
100✔
76
        }
77

78
        $this->callAfterApplicationCreatedCallbacks();
100✔
79

80
        Model::setEventDispatcher($app['events']);
100✔
81
    }
82

83
    /**
84
     * Teardown the testing hooks.
85
     *
86
     * @param  (\Closure():(void))|null  $callback
87
     * @return void
88
     *
89
     * @throws \Throwable
90
     */
91
    final protected function tearDownTheApplicationTestingHooks(?Closure $callback = null): void
92
    {
93
        if ($this->app) {
100✔
94
            $this->callBeforeApplicationDestroyedCallbacks();
100✔
95

96
            $this->tearDownParallelTestingCallbacks();
100✔
97

98
            $this->app?->flush();
100✔
99

100
            $this->app = null;
100✔
101
        }
102

103
        if (! \is_null($callback)) {
100✔
104
            \call_user_func($callback);
100✔
105
        }
106

107
        if (class_exists(Mockery::class)) {
100✔
108
            /** @phpstan-ignore-next-line */
109
            if ($container = Mockery::getContainer()) {
100✔
110
                $this->addToAssertionCount($container->mockery_getExpectationCount());
100✔
111
            }
112

113
            Mockery::close();
100✔
114
        }
115

116
        Carbon::setTestNow();
100✔
117

118
        if (class_exists(CarbonImmutable::class)) {
100✔
119
            CarbonImmutable::setTestNow();
100✔
120
        }
121

122
        $this->afterApplicationCreatedCallbacks = [];
100✔
123
        $this->beforeApplicationDestroyedCallbacks = [];
100✔
124

125
        Artisan::forgetBootstrappers();
100✔
126
        Component::flushCache();
100✔
127
        Component::forgetComponentsResolver();
100✔
128
        Component::forgetFactory();
100✔
129
        Queue::createPayloadUsing(null);
100✔
130
        HandleExceptions::forgetApp();
100✔
131

132
        if ($this->callbackException) {
100✔
133
            throw $this->callbackException;
×
134
        }
135
    }
136

137
    /**
138
     * Setup parallel testing callback.
139
     */
140
    protected function setUpParallelTestingCallbacks(): void
141
    {
142
        if (class_exists(ParallelTesting::class) && $this instanceof TestCase) {
100✔
143
            /** @phpstan-ignore-next-line */
144
            ParallelTesting::callSetUpTestCaseCallbacks($this);
100✔
145
        }
146
    }
147

148
    /**
149
     * Teardown parallel testing callback.
150
     */
151
    protected function tearDownParallelTestingCallbacks(): void
152
    {
153
        if (class_exists(ParallelTesting::class) && $this instanceof TestCase) {
100✔
154
            /** @phpstan-ignore-next-line */
155
            ParallelTesting::callTearDownTestCaseCallbacks($this);
100✔
156
        }
157
    }
158

159
    /**
160
     * Register a callback to be run after the application is refreshed.
161
     *
162
     * @param  callable():void  $callback
163
     * @return void
164
     */
165
    protected function afterApplicationRefreshed(callable $callback): void
166
    {
167
        $this->afterApplicationRefreshedCallbacks[] = $callback;
×
168

169
        if ($this->setUpHasRun) {
×
170
            \call_user_func($callback);
×
171
        }
172
    }
173

174
    /**
175
     * Execute the application's post-refreshed callbacks.
176
     *
177
     * @return void
178
     */
179
    protected function callAfterApplicationRefreshedCallbacks(): void
180
    {
181
        foreach ($this->afterApplicationRefreshedCallbacks as $callback) {
100✔
182
            \call_user_func($callback);
×
183
        }
184
    }
185

186
    /**
187
     * Register a callback to be run after the application is created.
188
     *
189
     * @param  callable():void  $callback
190
     * @return void
191
     */
192
    protected function afterApplicationCreated(callable $callback): void
193
    {
194
        $this->afterApplicationCreatedCallbacks[] = $callback;
2✔
195

196
        if ($this->setUpHasRun) {
2✔
197
            \call_user_func($callback);
1✔
198
        }
199
    }
200

201
    /**
202
     * Execute the application's post-creation callbacks.
203
     *
204
     * @return void
205
     */
206
    protected function callAfterApplicationCreatedCallbacks(): void
207
    {
208
        foreach ($this->afterApplicationCreatedCallbacks as $callback) {
100✔
209
            \call_user_func($callback);
1✔
210
        }
211
    }
212

213
    /**
214
     * Register a callback to be run before the application is destroyed.
215
     *
216
     * @param  callable():void  $callback
217
     * @return void
218
     */
219
    protected function beforeApplicationDestroyed(callable $callback): void
220
    {
221
        array_unshift($this->beforeApplicationDestroyedCallbacks, $callback);
100✔
222
    }
223

224
    /**
225
     * Execute the application's pre-destruction callbacks.
226
     *
227
     * @return void
228
     */
229
    protected function callBeforeApplicationDestroyedCallbacks(): void
230
    {
231
        foreach ($this->beforeApplicationDestroyedCallbacks as $callback) {
100✔
232
            try {
233
                \call_user_func($callback);
100✔
234
            } catch (Throwable $e) {
×
235
                if (! $this->callbackException) {
×
236
                    $this->callbackException = $e;
×
237
                }
238
            }
239
        }
240
    }
241

242
    /**
243
     * Refresh the application instance.
244
     *
245
     * @return void
246
     */
247
    abstract protected function refreshApplication();
248
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc