Created
June 17, 2023 12:05
-
-
Save hotsaucejake/a84b3439597f726870efd4c9e67f5870 to your computer and use it in GitHub Desktop.
Checksum Faster Refresh Database Trait for Laravel Tests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Tests; | |
use Illuminate\Contracts\Console\Kernel; | |
use Illuminate\Foundation\Testing\RefreshDatabase; | |
use Illuminate\Foundation\Testing\RefreshDatabaseState; | |
use Symfony\Component\Finder\Finder; | |
/** | |
* Only migrate fresh if necessary -> much faster after the first time! | |
*/ | |
trait FasterRefreshDatabase | |
{ | |
use RefreshDatabase; | |
/** | |
* Only migrates fresh if necessary | |
*/ | |
protected function refreshTestDatabase(): void | |
{ | |
if (!RefreshDatabaseState::$migrated) { | |
$this->runMigrationsIfNecessary(); | |
$this->app[Kernel::class]->setArtisan(null); | |
RefreshDatabaseState::$migrated = true; | |
} | |
$this->beginDatabaseTransaction(); | |
} | |
/** | |
* Check if migration fresh is necessary by checking | |
* if the migrations files checksum has changed. | |
*/ | |
protected function runMigrationsIfNecessary(): void | |
{ | |
if (!$this->identicalChecksum()) { | |
// $this->seed(); | |
$this->artisan('migrate:fresh', $this->migrateFreshUsing()); | |
//create checksum after migration finishes | |
$this->createChecksum(); | |
} | |
} | |
/** | |
* Calaculates the checksum of the migration files. | |
*/ | |
private function calculateChecksum(): string | |
{ | |
$files = Finder::create() | |
->files() | |
->exclude([ | |
'factories', | |
'seeders', | |
]) | |
->in(database_path()) | |
->ignoreDotFiles(true) | |
->ignoreVCS(true) | |
->getIterator(); | |
$files = array_keys(iterator_to_array($files)); | |
$checksum = collect($files)->map(function ($file) { | |
return md5_file($file); | |
})->implode(''); | |
return md5($checksum); | |
} | |
/** | |
* Filepath to store the checksum. | |
*/ | |
private function checksumFilePath(): string | |
{ | |
return base_path('.phpunit.database.checksum'); | |
} | |
/** | |
* Creates the checksum file. | |
*/ | |
private function createChecksum(): void | |
{ | |
file_put_contents($this->checksumFilePath(), $this->calculateChecksum()); | |
} | |
/** | |
* Get the checksum file content. | |
* | |
* @return false|string | |
*/ | |
private function checksumFileContents() | |
{ | |
return file_get_contents($this->checksumFilePath()); | |
} | |
/** | |
* Check if checksum exists. | |
*/ | |
private function isChecksumExists(): bool | |
{ | |
return file_exists($this->checksumFilePath()); | |
} | |
/** | |
* Check if checksum of current database migration files | |
* are identical to the one we stored already. | |
*/ | |
private function identicalChecksum(): bool | |
{ | |
if (!$this->isChecksumExists()) { | |
return false; | |
} | |
if ($this->checksumFileContents() === $this->calculateChecksum()) { | |
return true; | |
} | |
return false; | |
} | |
} |
Author
hotsaucejake
commented
Jun 17, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment