Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ listed, please submit an issue to this repository!
## Quick Example

This example is intended to reflect what should be capable with this library. We're going to
use [cspray/database-testing-phpunit]() as our testing extension, it is ubiquitous and likely the framework you'll start off using with this library.
use [cspray/database-testing-phpunit](https://github.com/cspray/databse-testing-phpunit) as our testing extension, it is ubiquitous and likely the framework you'll start off using with this library.

```php
<?php declare(strict_types=1);
Expand All @@ -46,6 +46,7 @@ use Cspray\DatabaseTesting\DatabaseCleanup\TransactionWithRollback;
use Cspray\DatabaseTesting\Fixture\LoadFixture;
use Cspray\DatabaseTesting\Fixture\SingleRecordFixture;
use Cspray\DatabaseTesting\TestDatabase;
use Cspray\DatabaseTesting\PhpUnit\InjectTestDatabase;
use Cspray\DatabaseTesting\PhpUnit\RequiresTestDatabase;
use PHPUnit\Framework\TestCase;
use PDO;
Expand All @@ -60,13 +61,16 @@ use PDO;
)]
final class RepositoryTest extends TestCase {

#[InjectTestDatabase]
private static TestDatabase $testDatabase;

private PDO $pdo;
private MyRepository $myRepository;

protected function setUp() : void {
// be sure to use the connection from TestDatabase! depending on CleanupStrategy,
// using a different connection could wind up with a dirty database state
$this->pdo = TestDatabase::connection();
$this->pdo = self::$testDatabase->connection();
$this->myRepository = new MyRepository($this->pdo);
}

Expand All @@ -79,7 +83,7 @@ final class RepositoryTest extends TestCase {
])
)]
public function testTableHasCorrectlyLoadedFixtures() : void {
$table = TestDatabase::table('my_table');
$table = self::$testDatabase->table('my_table');

self::assertCount(1, $table);

Expand All @@ -88,7 +92,7 @@ final class RepositoryTest extends TestCase {
}

public function testTableCanBeReloadedToGetNewlyInsertedRecords() : void {
$table = TestDatabase::table('my_table');
$table = self::$testDatabase->table('my_table');

self::assertCount(0, $table);

Expand All @@ -101,5 +105,3 @@ final class RepositoryTest extends TestCase {

}
```


29 changes: 13 additions & 16 deletions src/Internal/ConnectionAdapterTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ public function testInsertAfterEstablishingConnectionResultsInAppropriateRecords

public function testBeginTransactionAndRollbackResultsInRecordsNotPersisted() : void {
$this->connectionAdapter->establishConnection();
//

$sql = 'SELECT * FROM my_table';
// $records = $this->executeSelectSql($sql);
//
// self::assertEmpty($records);
$records = $this->executeSelectSql($sql);

self::assertEmpty($records);

$this->connectionAdapter->beginTransaction();

Expand Down Expand Up @@ -171,29 +171,26 @@ public function testFetchingTableFromConnectionAdapterAllowsInspectingCorrectRec
new SingleRecordFixture('my_table', ['name' => 'Harry']),
]);

$table = $this->connectionAdapter->selectAll('my_table');
$data = $this->connectionAdapter->selectAll('my_table');

self::assertSame('my_table', $table->name());
self::assertCount(1, $table);
self::assertSame('Harry', $table->row(0)->get('name'));
self::assertCount(1, $data);
self::assertSame('Harry', $data[0]['name']);

$this->connectionAdapter->insert([
new SingleRecordFixture('my_table', ['name' => 'Mack']),
]);

$table->reload();
$newData = $this->connectionAdapter->selectAll('my_table');

self::assertSame('my_table', $table->name());
self::assertCount(2, $table);
self::assertSame('Harry', $table->row(0)->get('name'));
self::assertSame('Mack', $table->row(1)->get('name'));
self::assertCount(2, $newData);
self::assertSame('Harry', $newData[0]['name']);
self::assertSame('Mack', $newData[1]['name']);

$this->connectionAdapter->truncateTable('my_table');

$table->reload();
$truncatedData = $this->connectionAdapter->selectAll('my_table');

self::assertSame('my_table', $table->name());
self::assertCount(0, $table);
self::assertCount(0, $truncatedData);
}


Expand Down
84 changes: 19 additions & 65 deletions src/TestDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@
namespace Cspray\DatabaseTesting;

use Cspray\DatabaseTesting\ConnectionAdapter\ConnectionAdapter;
use Cspray\DatabaseTesting\ConnectionAdapter\ConnectionAdapterFactory;
use Cspray\DatabaseTesting\DatabaseCleanup\CleanupStrategy;
use Cspray\DatabaseTesting\DatabaseRepresentation\Table;
use Cspray\DatabaseTesting\Exception\ConnectionAlreadyEstablished;
use Cspray\DatabaseTesting\Exception\ConnectionNotEstablished;
use Cspray\DatabaseTesting\Fixture\Fixture;
use Cspray\DatabaseTesting\Internal\ClosureDataProviderTable;

/**
Expand All @@ -18,80 +15,37 @@
*/
final class TestDatabase {

private static ?ConnectionAdapter $connectionAdapter = null;

private function __construct(
private readonly string $testClass,
private readonly ConnectionAdapterFactory $connectionAdapterFactory,
private readonly CleanupStrategy $cleanupStrategy,
private readonly ConnectionAdapter $connectionAdapter,
) {}

/**
* @param class-string $class
* @param RequiresTestDatabaseSettings $requiresTestDatabase
* @return self
*@internal
*/
public static function createFromTestCaseRequiresDatabase(
string $class,
RequiresTestDatabaseSettings $requiresTestDatabase
) : self {
return new self(
$class,
$requiresTestDatabase->connectionAdapterFactory(),
$requiresTestDatabase->cleanupStrategy()
);
}

/**
* Allow for introspection of a database table.
*
* @param non-empty-string $name
* @return Table
*/
public static function table(string $name) : Table {
self::verifyConnectionEstablished(__METHOD__);
return new ClosureDataProviderTable($name, fn() => self::$connectionAdapter->selectAll($name));
public function connectionAdapter() : ConnectionAdapter {
return $this->connectionAdapter;
}

/**
* @template UnderlyingConnection of object
* @return UnderlyingConnection
*/
public static function connection() : object {
self::verifyConnectionEstablished(__METHOD__);
return self::$connectionAdapter->underlyingConnection();
}

public function establishConnection() : void {
if (self::$connectionAdapter !== null) {
throw ConnectionAlreadyEstablished::fromConnectionAlreadyEstablished();
}
self::$connectionAdapter = $this->connectionAdapterFactory->createConnectionAdapter();
self::$connectionAdapter->establishConnection();
public function connection() : object {
return $this->connectionAdapter->underlyingConnection();
}

public function prepareForTest(DatabaseAwareTest $databaseAwareTest) : void {
self::verifyConnectionEstablished(__METHOD__);
$this->cleanupStrategy->cleanupBeforeTest($databaseAwareTest, self::$connectionAdapter);
self::$connectionAdapter->insert($databaseAwareTest->fixtures());
}

public function cleanupAfterTest(DatabaseAwareTest $databaseAwareTest) : void {
self::verifyConnectionEstablished(__METHOD__);
$this->cleanupStrategy->teardownAfterTest($databaseAwareTest, self::$connectionAdapter);
}

public function closeConnection() : void {
self::verifyConnectionEstablished(__METHOD__);
self::$connectionAdapter->closeConnection();
self::$connectionAdapter = null;
/**
* @param list<Fixture> $fixtures
*/
public function loadFixtures(array $fixtures) : void {
$this->connectionAdapter->insert($fixtures);
}

private static function verifyConnectionEstablished(string $method) : void {
if (self::$connectionAdapter === null) {
throw ConnectionNotEstablished::fromInvalidInvocationBeforeConnectionEstablished($method);
}
/**
* Allow for introspection of a database table.
*
* @param non-empty-string $name
* @return Table
*/
public function table(string $name) : Table {
return new ClosureDataProviderTable($name, fn() => $this->connectionAdapter->selectAll($name));
}

}
Loading