Revision 148 | Blame | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed
<?phpnamespace Illuminate\Testing\Concerns;use Illuminate\Database\QueryException;use Illuminate\Foundation\Testing;use Illuminate\Support\Arr;use Illuminate\Support\Facades\Artisan;use Illuminate\Support\Facades\DB;use Illuminate\Support\Facades\ParallelTesting;use Illuminate\Support\Facades\Schema;trait TestDatabases{/*** Indicates if the test database schema is up to date.** @var bool*/protected static $schemaIsUpToDate = false;/*** Boot a test database.** @return void*/protected function bootTestDatabase(){ParallelTesting::setUpProcess(function () {$this->whenNotUsingInMemoryDatabase(function ($database) {if (ParallelTesting::option('recreate_databases')) {Schema::dropDatabaseIfExists($this->testDatabase($database));}});});ParallelTesting::setUpTestCase(function ($testCase) {$uses = array_flip(class_uses_recursive(get_class($testCase)));$databaseTraits = [Testing\DatabaseMigrations::class,Testing\DatabaseTransactions::class,Testing\DatabaseTruncation::class,Testing\RefreshDatabase::class,];if (Arr::hasAny($uses, $databaseTraits) && ! ParallelTesting::option('without_databases')) {$this->whenNotUsingInMemoryDatabase(function ($database) use ($uses) {[$testDatabase, $created] = $this->ensureTestDatabaseExists($database);$this->switchToDatabase($testDatabase);if (isset($uses[Testing\DatabaseTransactions::class])) {$this->ensureSchemaIsUpToDate();}if ($created) {ParallelTesting::callSetUpTestDatabaseCallbacks($testDatabase);}});}});ParallelTesting::tearDownProcess(function () {$this->whenNotUsingInMemoryDatabase(function ($database) {if (ParallelTesting::option('drop_databases')) {Schema::dropDatabaseIfExists($this->testDatabase($database));}});});}/*** Ensure a test database exists and returns its name.** @param string $database* @return array*/protected function ensureTestDatabaseExists($database){$testDatabase = $this->testDatabase($database);try {$this->usingDatabase($testDatabase, function () {Schema::hasTable('dummy');});} catch (QueryException $e) {$this->usingDatabase($database, function () use ($testDatabase) {Schema::dropDatabaseIfExists($testDatabase);Schema::createDatabase($testDatabase);});return [$testDatabase, true];}return [$testDatabase, false];}/*** Ensure the current database test schema is up to date.** @return void*/protected function ensureSchemaIsUpToDate(){if (! static::$schemaIsUpToDate) {Artisan::call('migrate');static::$schemaIsUpToDate = true;}}/*** Runs the given callable using the given database.** @param string $database* @param callable $callable* @return void*/protected function usingDatabase($database, $callable){$original = DB::getConfig('database');try {$this->switchToDatabase($database);$callable();} finally {$this->switchToDatabase($original);}}/*** Apply the given callback when tests are not using in memory database.** @param callable $callback* @return void*/protected function whenNotUsingInMemoryDatabase($callback){$database = DB::getConfig('database');if ($database !== ':memory:') {$callback($database);}}/*** Switch to the given database.** @param string $database* @return void*/protected function switchToDatabase($database){DB::purge();$default = config('database.default');$url = config("database.connections.{$default}.url");if ($url) {config()->set("database.connections.{$default}.url",preg_replace('/^(.*)(\/[\w-]*)(\??.*)$/', "$1/{$database}$3", $url),);} else {config()->set("database.connections.{$default}.database",$database,);}}/*** Returns the test database name.** @return string*/protected function testDatabase($database){$token = ParallelTesting::token();return "{$database}_test_{$token}";}}