death-notifier/src/test/php/com/fwdekker/deathnotifier/DatabaseTestCase.php

97 lines
3.0 KiB
PHP

<?php
namespace com\fwdekker\deathnotifier;
use com\fwdekker\deathnotifier\mailer\EmailQueue;
use com\fwdekker\deathnotifier\tracking\TrackingList;
use com\fwdekker\deathnotifier\user\UserList;
use Exception;
use PHPUnit\Framework\TestCase;
/**
* Provides a fresh database for each test.
*
* By default, the fields {@see DatabaseTestCase::$email_queue}, {@see DatabaseTestCase::$user_list}, and
* {@see DatabaseTestCase::$tracking_list} are mocks, and hence their `install` methods are not called. To change this,
* override {@see DatabaseTestCase::setUpWithDatabase()}.
*/
abstract class DatabaseTestCase extends TestCase
{
/**
* @var string the temporary directory to store database files in
*/
private static string $db_tmp_dir;
/**
* @var Database the database
*/
public Database $database;
/**
* @var EmailQueue the `EmailQueue` to install the database schema of
*/
public EmailQueue $email_queue;
/**
* @var UserList the `UserList` to install the database schema of
*/
public UserList $user_list;
/**
* @var TrackingList the `TrackingList` to install the database schema of
*/
public TrackingList $tracking_list;
/**
* Sets up a directory for temporary files.
*
* @throws Exception if the directory could not be created
*/
public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();
self::$db_tmp_dir = sys_get_temp_dir() . "/DatabaseTestCase-" . rand();
if (!mkdir(self::$db_tmp_dir))
throw new Exception("Failed to create temporary directory '" . self::$db_tmp_dir . "'.");
register_shutdown_function(function () {
$files = glob(self::$db_tmp_dir . "/*");
if ($files === false) return;
array_map("unlink", $files);
});
}
/**
* Sets up and installs a database.
*
* @throws Exception if the database file could not be created
*/
public function setUp(): void
{
parent::setUp();
$db_tmp_file = tempnam(self::$db_tmp_dir, "database-");
if ($db_tmp_file === false) throw new Exception("Failed to create temporary database file.");
$this->database = new Database($db_tmp_file);
$this->setUpWithDatabase($this->database);
$this->database->auto_install($this->email_queue, $this->user_list, $this->tracking_list);
}
/**
* Creates the {@see EmailQueue}, {@see UserList}, and {@see TrackingList} using {@see $database}.
*
* By default, all three structures are stubs. Override this method to change that.
*
* @param Database $database the `Database` with which to instantiate the structures
* @return void
*/
public function setUpWithDatabase(Database $database): void
{
$this->email_queue = $this->createStub(EmailQueue::class);
$this->user_list = $this->createStub(UserList::class);
$this->tracking_list = $this->createStub(TrackingList::class);
}
}