Added testing
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,3 +4,5 @@
|
|||||||
|
|
||||||
# PHPStorm
|
# PHPStorm
|
||||||
**/.idea/
|
**/.idea/
|
||||||
|
|
||||||
|
**/.cache/
|
||||||
|
22
Dockerfile
Normal file
22
Dockerfile
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
FROM composer:lts as deps
|
||||||
|
WORKDIR /app
|
||||||
|
RUN --mount=type=bind,source=./composer.json,target=composer.json \
|
||||||
|
--mount=type=bind,source=./composer.lock,target=composer.lock \
|
||||||
|
--mount=type=cache,target=/tmp/cache \
|
||||||
|
composer install --no-interaction
|
||||||
|
|
||||||
|
FROM php:8-cli as base
|
||||||
|
WORKDIR /app
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -yq --no-install-recommends libsqlite3-dev && \
|
||||||
|
rm -rf /var/lib/apt/lists/* && \
|
||||||
|
docker-php-ext-install pdo pdo_sqlite
|
||||||
|
COPY ./src /app/src
|
||||||
|
|
||||||
|
FROM base as dev
|
||||||
|
COPY ./tests /app/tests
|
||||||
|
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
|
||||||
|
COPY --from=deps /app/vendor/ /app/vendor
|
||||||
|
|
||||||
|
FROM dev as test
|
||||||
|
ENTRYPOINT [ "./vendor/bin/phpunit" ]
|
5
compose.yml
Normal file
5
compose.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
services:
|
||||||
|
database:
|
||||||
|
build: .
|
||||||
|
volumes:
|
||||||
|
- ./:/app
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "provm/database",
|
"name": "provm/database",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
|
"version": "1.2.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Aldarien",
|
"name": "Aldarien",
|
||||||
@ -12,8 +13,7 @@
|
|||||||
"ext-pdo": "*"
|
"ext-pdo": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^10.0",
|
"phpunit/phpunit": "^10.0"
|
||||||
"kint-php/kint": "^5.0"
|
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
28
phpunit.xml
Normal file
28
phpunit.xml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
|
||||||
|
bootstrap="vendor/autoload.php"
|
||||||
|
cacheResultFile=".cache/test-results"
|
||||||
|
executionOrder="depends,defects"
|
||||||
|
forceCoversAnnotation="false"
|
||||||
|
beStrictAboutCoversAnnotation="true"
|
||||||
|
beStrictAboutOutputDuringTests="true"
|
||||||
|
beStrictAboutTodoAnnotatedTests="true"
|
||||||
|
convertDeprecationsToExceptions="true"
|
||||||
|
colors="true"
|
||||||
|
failOnRisky="true"
|
||||||
|
failOnWarning="true"
|
||||||
|
verbose="true">
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="default">
|
||||||
|
<directory>tests</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
|
||||||
|
<coverage cacheDirectory=".cache/code-coverage"
|
||||||
|
processUncoveredFiles="true">
|
||||||
|
<include>
|
||||||
|
<directory suffix=".php">src</directory>
|
||||||
|
</include>
|
||||||
|
</coverage>
|
||||||
|
</phpunit>
|
@ -3,6 +3,7 @@ namespace ProVM\Database;
|
|||||||
|
|
||||||
use PDO;
|
use PDO;
|
||||||
use ProVM\Concept\Database;
|
use ProVM\Concept\Database;
|
||||||
|
use ProVM\Exception\Database\InvalidQuery;
|
||||||
|
|
||||||
class Connection implements Database\Connection
|
class Connection implements Database\Connection
|
||||||
{
|
{
|
||||||
@ -50,11 +51,19 @@ class Connection implements Database\Connection
|
|||||||
|
|
||||||
public function query(string $query): Database\ResultSet
|
public function query(string $query): Database\ResultSet
|
||||||
{
|
{
|
||||||
return new ResultSet($this->connect()->query($query));
|
$statement = $this->connect()->query($query);
|
||||||
|
if ($statement === false) {
|
||||||
|
throw new InvalidQuery($query);
|
||||||
|
}
|
||||||
|
return new ResultSet($statement);
|
||||||
}
|
}
|
||||||
public function prepare(string $query): Database\ResultSet
|
public function prepare(string $query): Database\ResultSet
|
||||||
{
|
{
|
||||||
return new ResultSet($this->connect()->prepare($query));
|
$statement = $this->connect()->prepare($query);
|
||||||
|
if ($statement === false) {
|
||||||
|
throw new InvalidQuery($query);
|
||||||
|
}
|
||||||
|
return new ResultSet($statement);
|
||||||
}
|
}
|
||||||
public function execute(string $query, ?array $data = null): Database\ResultSet
|
public function execute(string $query, ?array $data = null): Database\ResultSet
|
||||||
{
|
{
|
||||||
@ -65,4 +74,13 @@ class Connection implements Database\Connection
|
|||||||
}
|
}
|
||||||
return $this->query($query);
|
return $this->query($query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function fetchOne(string $query, ?array $data = null): array
|
||||||
|
{
|
||||||
|
return $this->execute($query, $data)->fetchFirst();
|
||||||
|
}
|
||||||
|
public function fetchMany(string $query, ?array $data = null): array
|
||||||
|
{
|
||||||
|
return $this->execute($query, $data)->fetchAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
14
src/Exception/Database/InvalidQuery.php
Normal file
14
src/Exception/Database/InvalidQuery.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
namespace ProVM\Exception\Database;
|
||||||
|
|
||||||
|
use Throwable;
|
||||||
|
use ProVM\Exception;
|
||||||
|
|
||||||
|
class InvalidQuery extends Exception\Database
|
||||||
|
{
|
||||||
|
public function __construct(string $query, ?Throwable $previous = null)
|
||||||
|
{
|
||||||
|
$message = "Invalid query \"{$query}\"";
|
||||||
|
parent::__construct($message, 0, $previous);
|
||||||
|
}
|
||||||
|
}
|
65
tests/ConnectionTest.php
Normal file
65
tests/ConnectionTest.php
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
use ProVM\Database\Connection;
|
||||||
|
use ProVM\Concept;
|
||||||
|
|
||||||
|
class ConnectionTest extends TestCase
|
||||||
|
{
|
||||||
|
protected PDO $pdo;
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
$this->pdo = new PDO('sqlite::memory:');
|
||||||
|
$query = "CREATE TABLE IF NOT EXISTS test_table (id INTEGER PRIMARY KEY, test TEXT)";
|
||||||
|
$this->pdo->query($query);
|
||||||
|
}
|
||||||
|
protected function tearDown(): void
|
||||||
|
{
|
||||||
|
unset($this->pdo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConnection()
|
||||||
|
{
|
||||||
|
$host = "memory";
|
||||||
|
|
||||||
|
$database = $this->getMockBuilder(Concept\Database::class)->getMock();
|
||||||
|
$database->method('getHost')->willReturn($host);
|
||||||
|
$database->method('getDsn')->willReturn("sqlite::{$host}");
|
||||||
|
$database->method('needsUser')->willReturn(false);
|
||||||
|
|
||||||
|
$connection = new Connection($database);
|
||||||
|
$this->assertEquals($this->pdo, $connection->connect());
|
||||||
|
}
|
||||||
|
public function testQuery()
|
||||||
|
{
|
||||||
|
$host = "memory";
|
||||||
|
|
||||||
|
$database = $this->getMockBuilder(Concept\Database::class)->getMock();
|
||||||
|
$database->method('getHost')->willReturn($host);
|
||||||
|
$database->method('getDsn')->willReturn("sqlite::{$host}");
|
||||||
|
$database->method('needsUser')->willReturn(false);
|
||||||
|
|
||||||
|
$connection = new Connection($database);
|
||||||
|
$query = "CREATE TABLE IF NOT EXISTS test_table (id INTEGER PRIMARY KEY, test TEXT)";
|
||||||
|
$connection->query($query);
|
||||||
|
$query = "SELECT * FROM test_table";
|
||||||
|
$result = $connection->query($query);
|
||||||
|
$this->assertInstanceOf(Concept\Database\ResultSet::class, $result);
|
||||||
|
}
|
||||||
|
public function testPrepare()
|
||||||
|
{
|
||||||
|
$host = "memory";
|
||||||
|
|
||||||
|
$database = $this->getMockBuilder(Concept\Database::class)->getMock();
|
||||||
|
$database->method('getHost')->willReturn($host);
|
||||||
|
$database->method('getDsn')->willReturn("sqlite::{$host}");
|
||||||
|
$database->method('needsUser')->willReturn(false);
|
||||||
|
|
||||||
|
$connection = new Connection($database);
|
||||||
|
$query = "CREATE TABLE IF NOT EXISTS test_table (id INTEGER PRIMARY KEY, test TEXT)";
|
||||||
|
$connection->query($query);
|
||||||
|
$query = "SELECT * FROM test_table";
|
||||||
|
$result = $connection->prepare($query);
|
||||||
|
$this->assertInstanceOf(Concept\Database\ResultSet::class, $result);
|
||||||
|
}
|
||||||
|
}
|
32
tests/MySQLTest.php
Normal file
32
tests/MySQLTest.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use ProVM\Database\MySQL;
|
||||||
|
|
||||||
|
class MySQLTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testDatabase()
|
||||||
|
{
|
||||||
|
$host = "testhost";
|
||||||
|
$port = 1234;
|
||||||
|
$name = "testdb";
|
||||||
|
$user = "testuser";
|
||||||
|
$pass = "testpass";
|
||||||
|
|
||||||
|
$dsn = "mysql:host={$host};port={$port};dbname={$name}";
|
||||||
|
|
||||||
|
$database = new MySQL();
|
||||||
|
$database->setHost($host);
|
||||||
|
$database->setPort($port);
|
||||||
|
$database->setName($name);
|
||||||
|
$database->setUser($user);
|
||||||
|
$database->setPassword($pass);
|
||||||
|
|
||||||
|
$this->assertEquals($host, $database->getHost());
|
||||||
|
$this->assertEquals($port, $database->getPort());
|
||||||
|
$this->assertEquals($name, $database->getName());
|
||||||
|
$this->assertEquals($user, $database->getUser());
|
||||||
|
$this->assertEquals($pass, $database->getPassword());
|
||||||
|
$this->assertTrue($database->needsUser());
|
||||||
|
$this->assertEquals($dsn, $database->getDsn());
|
||||||
|
}
|
||||||
|
}
|
32
tests/PostgreSQLTest.php
Normal file
32
tests/PostgreSQLTest.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use ProVM\Database\PostgreSQL;
|
||||||
|
|
||||||
|
class PostgreSQLTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testDatabase()
|
||||||
|
{
|
||||||
|
$host = "testhost";
|
||||||
|
$port = 1234;
|
||||||
|
$name = "testdb";
|
||||||
|
$user = "testuser";
|
||||||
|
$pass = "testpass";
|
||||||
|
|
||||||
|
$dsn = "pgsql:host={$host};port={$port};dbname={$name};user={$user};password={$pass}";
|
||||||
|
|
||||||
|
$database = new PostgreSQL();
|
||||||
|
$database->setHost($host);
|
||||||
|
$database->setPort($port);
|
||||||
|
$database->setName($name);
|
||||||
|
$database->setUser($user);
|
||||||
|
$database->setPassword($pass);
|
||||||
|
|
||||||
|
$this->assertEquals($host, $database->getHost());
|
||||||
|
$this->assertEquals($port, $database->getPort());
|
||||||
|
$this->assertEquals($name, $database->getName());
|
||||||
|
$this->assertEquals($user, $database->getUser());
|
||||||
|
$this->assertEquals($pass, $database->getPassword());
|
||||||
|
$this->assertFalse($database->needsUser());
|
||||||
|
$this->assertEquals($dsn, $database->getDsn());
|
||||||
|
}
|
||||||
|
}
|
26
tests/ResultSetTest.php
Normal file
26
tests/ResultSetTest.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
use ProVM\Database\ResultSet;
|
||||||
|
|
||||||
|
class ResultSetTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testResultSet()
|
||||||
|
{
|
||||||
|
$result1 = ['col1', 'col2', 'col3'];
|
||||||
|
$result2 = [['col1', 'col2'], ['col3', 'col4']];
|
||||||
|
|
||||||
|
$statement = $this->getMockBuilder(PDOStatement::class)->getMock();
|
||||||
|
$statement->method('execute')->willReturn(true);
|
||||||
|
$statement->method('fetch')->willReturn($result1);
|
||||||
|
$statement->method('fetchAll')->willReturn($result2);
|
||||||
|
$statement->method('rowCount')->willReturn(2);
|
||||||
|
|
||||||
|
$resultSet = new ResultSet($statement);
|
||||||
|
|
||||||
|
$resultSet->execute(['foo' => 'bar']);
|
||||||
|
$this->assertTrue(true);
|
||||||
|
$this->assertEquals($result1, $resultSet->fetchFirst());
|
||||||
|
$this->assertEquals($result2, $resultSet->fetchAll());
|
||||||
|
}
|
||||||
|
}
|
20
tests/SQLiteTest.php
Normal file
20
tests/SQLiteTest.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use ProVM\Database\SQLite;
|
||||||
|
|
||||||
|
class SQLiteTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testDatabase()
|
||||||
|
{
|
||||||
|
$host = ":memory:";
|
||||||
|
|
||||||
|
$dsn = "sqlite:{$host}";
|
||||||
|
|
||||||
|
$database = new SQLite();
|
||||||
|
$database->setHost($host);
|
||||||
|
|
||||||
|
$this->assertEquals($host, $database->getHost());
|
||||||
|
$this->assertFalse($database->needsUser());
|
||||||
|
$this->assertEquals($dsn, $database->getDsn());
|
||||||
|
}
|
||||||
|
}
|
19
tests/TransactionTest.php
Normal file
19
tests/TransactionTest.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use ProVM\Database\Transaction;
|
||||||
|
|
||||||
|
class TransactionTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testTransaction()
|
||||||
|
{
|
||||||
|
$connection = $this->createMock(ProVM\Concept\Database\Connection::class);
|
||||||
|
$transaction = new Transaction($connection);
|
||||||
|
$transaction->begin();
|
||||||
|
$this->assertTrue(true);
|
||||||
|
$transaction->commit();
|
||||||
|
$this->assertTrue(true);
|
||||||
|
$transaction->begin();
|
||||||
|
$transaction->rollback();
|
||||||
|
$this->assertTrue(true);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user