Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Details | Vergleich mit vorheriger | 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,
399 lars 45
                Testing\DatabaseTruncation::class,
148 lars 46
                Testing\RefreshDatabase::class,
47
            ];
48
 
49
            if (Arr::hasAny($uses, $databaseTraits) && ! ParallelTesting::option('without_databases')) {
50
                $this->whenNotUsingInMemoryDatabase(function ($database) use ($uses) {
51
                    [$testDatabase, $created] = $this->ensureTestDatabaseExists($database);
52
 
53
                    $this->switchToDatabase($testDatabase);
54
 
55
                    if (isset($uses[Testing\DatabaseTransactions::class])) {
56
                        $this->ensureSchemaIsUpToDate();
57
                    }
58
 
59
                    if ($created) {
60
                        ParallelTesting::callSetUpTestDatabaseCallbacks($testDatabase);
61
                    }
62
                });
63
            }
64
        });
65
 
66
        ParallelTesting::tearDownProcess(function () {
67
            $this->whenNotUsingInMemoryDatabase(function ($database) {
68
                if (ParallelTesting::option('drop_databases')) {
69
                    Schema::dropDatabaseIfExists(
70
                        $this->testDatabase($database)
71
                    );
72
                }
73
            });
74
        });
75
    }
76
 
77
    /**
78
     * Ensure a test database exists and returns its name.
79
     *
80
     * @param  string  $database
81
     * @return array
82
     */
83
    protected function ensureTestDatabaseExists($database)
84
    {
85
        $testDatabase = $this->testDatabase($database);
86
 
87
        try {
88
            $this->usingDatabase($testDatabase, function () {
89
                Schema::hasTable('dummy');
90
            });
91
        } catch (QueryException $e) {
92
            $this->usingDatabase($database, function () use ($testDatabase) {
93
                Schema::dropDatabaseIfExists($testDatabase);
94
                Schema::createDatabase($testDatabase);
95
            });
96
 
97
            return [$testDatabase, true];
98
        }
99
 
100
        return [$testDatabase, false];
101
    }
102
 
103
    /**
104
     * Ensure the current database test schema is up to date.
105
     *
106
     * @return void
107
     */
108
    protected function ensureSchemaIsUpToDate()
109
    {
110
        if (! static::$schemaIsUpToDate) {
111
            Artisan::call('migrate');
112
 
113
            static::$schemaIsUpToDate = true;
114
        }
115
    }
116
 
117
    /**
118
     * Runs the given callable using the given database.
119
     *
120
     * @param  string  $database
121
     * @param  callable  $callable
122
     * @return void
123
     */
124
    protected function usingDatabase($database, $callable)
125
    {
126
        $original = DB::getConfig('database');
127
 
128
        try {
129
            $this->switchToDatabase($database);
130
            $callable();
131
        } finally {
132
            $this->switchToDatabase($original);
133
        }
134
    }
135
 
136
    /**
137
     * Apply the given callback when tests are not using in memory database.
138
     *
139
     * @param  callable  $callback
140
     * @return void
141
     */
142
    protected function whenNotUsingInMemoryDatabase($callback)
143
    {
144
        $database = DB::getConfig('database');
145
 
146
        if ($database !== ':memory:') {
147
            $callback($database);
148
        }
149
    }
150
 
151
    /**
152
     * Switch to the given database.
153
     *
154
     * @param  string  $database
155
     * @return void
156
     */
157
    protected function switchToDatabase($database)
158
    {
159
        DB::purge();
160
 
161
        $default = config('database.default');
162
 
163
        $url = config("database.connections.{$default}.url");
164
 
165
        if ($url) {
166
            config()->set(
167
                "database.connections.{$default}.url",
168
                preg_replace('/^(.*)(\/[\w-]*)(\??.*)$/', "$1/{$database}$3", $url),
169
            );
170
        } else {
171
            config()->set(
172
                "database.connections.{$default}.database",
173
                $database,
174
            );
175
        }
176
    }
177
 
178
    /**
179
     * Returns the test database name.
180
     *
181
     * @return string
182
     */
183
    protected function testDatabase($database)
184
    {
185
        $token = ParallelTesting::token();
186
 
187
        return "{$database}_test_{$token}";
188
    }
189
}