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\Testing\Concerns;
4
 
5
use Illuminate\Database\QueryException;
6
use Illuminate\Foundation\Testing;
7
use Illuminate\Support\Arr;
8
use Illuminate\Support\Facades\Artisan;
9
use Illuminate\Support\Facades\DB;
10
use Illuminate\Support\Facades\ParallelTesting;
11
use Illuminate\Support\Facades\Schema;
12
 
13
trait TestDatabases
14
{
15
    /**
16
     * Indicates if the test database schema is up to date.
17
     *
18
     * @var bool
19
     */
20
    protected static $schemaIsUpToDate = false;
21
 
22
    /**
23
     * Boot a test database.
24
     *
25
     * @return void
26
     */
27
    protected function bootTestDatabase()
28
    {
29
        ParallelTesting::setUpProcess(function () {
30
            $this->whenNotUsingInMemoryDatabase(function ($database) {
31
                if (ParallelTesting::option('recreate_databases')) {
32
                    Schema::dropDatabaseIfExists(
33
                        $this->testDatabase($database)
34
                    );
35
                }
36
            });
37
        });
38
 
39
        ParallelTesting::setUpTestCase(function ($testCase) {
40
            $uses = array_flip(class_uses_recursive(get_class($testCase)));
41
 
42
            $databaseTraits = [
43
                Testing\DatabaseMigrations::class,
44
                Testing\DatabaseTransactions::class,
45
                Testing\RefreshDatabase::class,
46
            ];
47
 
48
            if (Arr::hasAny($uses, $databaseTraits) && ! ParallelTesting::option('without_databases')) {
49
                $this->whenNotUsingInMemoryDatabase(function ($database) use ($uses) {
50
                    [$testDatabase, $created] = $this->ensureTestDatabaseExists($database);
51
 
52
                    $this->switchToDatabase($testDatabase);
53
 
54
                    if (isset($uses[Testing\DatabaseTransactions::class])) {
55
                        $this->ensureSchemaIsUpToDate();
56
                    }
57
 
58
                    if ($created) {
59
                        ParallelTesting::callSetUpTestDatabaseCallbacks($testDatabase);
60
                    }
61
                });
62
            }
63
        });
64
 
65
        ParallelTesting::tearDownProcess(function () {
66
            $this->whenNotUsingInMemoryDatabase(function ($database) {
67
                if (ParallelTesting::option('drop_databases')) {
68
                    Schema::dropDatabaseIfExists(
69
                        $this->testDatabase($database)
70
                    );
71
                }
72
            });
73
        });
74
    }
75
 
76
    /**
77
     * Ensure a test database exists and returns its name.
78
     *
79
     * @param  string  $database
80
     * @return array
81
     */
82
    protected function ensureTestDatabaseExists($database)
83
    {
84
        $testDatabase = $this->testDatabase($database);
85
 
86
        try {
87
            $this->usingDatabase($testDatabase, function () {
88
                Schema::hasTable('dummy');
89
            });
90
        } catch (QueryException $e) {
91
            $this->usingDatabase($database, function () use ($testDatabase) {
92
                Schema::dropDatabaseIfExists($testDatabase);
93
                Schema::createDatabase($testDatabase);
94
            });
95
 
96
            return [$testDatabase, true];
97
        }
98
 
99
        return [$testDatabase, false];
100
    }
101
 
102
    /**
103
     * Ensure the current database test schema is up to date.
104
     *
105
     * @return void
106
     */
107
    protected function ensureSchemaIsUpToDate()
108
    {
109
        if (! static::$schemaIsUpToDate) {
110
            Artisan::call('migrate');
111
 
112
            static::$schemaIsUpToDate = true;
113
        }
114
    }
115
 
116
    /**
117
     * Runs the given callable using the given database.
118
     *
119
     * @param  string  $database
120
     * @param  callable  $callable
121
     * @return void
122
     */
123
    protected function usingDatabase($database, $callable)
124
    {
125
        $original = DB::getConfig('database');
126
 
127
        try {
128
            $this->switchToDatabase($database);
129
            $callable();
130
        } finally {
131
            $this->switchToDatabase($original);
132
        }
133
    }
134
 
135
    /**
136
     * Apply the given callback when tests are not using in memory database.
137
     *
138
     * @param  callable  $callback
139
     * @return void
140
     */
141
    protected function whenNotUsingInMemoryDatabase($callback)
142
    {
143
        $database = DB::getConfig('database');
144
 
145
        if ($database !== ':memory:') {
146
            $callback($database);
147
        }
148
    }
149
 
150
    /**
151
     * Switch to the given database.
152
     *
153
     * @param  string  $database
154
     * @return void
155
     */
156
    protected function switchToDatabase($database)
157
    {
158
        DB::purge();
159
 
160
        $default = config('database.default');
161
 
162
        $url = config("database.connections.{$default}.url");
163
 
164
        if ($url) {
165
            config()->set(
166
                "database.connections.{$default}.url",
167
                preg_replace('/^(.*)(\/[\w-]*)(\??.*)$/', "$1/{$database}$3", $url),
168
            );
169
        } else {
170
            config()->set(
171
                "database.connections.{$default}.database",
172
                $database,
173
            );
174
        }
175
    }
176
 
177
    /**
178
     * Returns the test database name.
179
     *
180
     * @return string
181
     */
182
    protected function testDatabase($database)
183
    {
184
        $token = ParallelTesting::token();
185
 
186
        return "{$database}_test_{$token}";
187
    }
188
}