Implement most unit tests

This commit is contained in:
2024-09-27 16:14:32 +02:00
parent 010911c684
commit 06ebef2a44
6 changed files with 269 additions and 19 deletions

View File

@ -20,10 +20,19 @@ class Daemon
private Database $db;
public function __construct(private string $databaseFile)
{
$this->db = new Database($this->databaseFile);
}
public function getDatabase(): Database
{
return $this->db;
}
public function start(): self
{
$this->db = new Database("/tmp/foo.db");
$this->listener = new TcpServer("0.0.0.0:8000");
$this->http = new HttpServer(
@ -56,7 +65,7 @@ class Daemon
}
}
private function onRequest(ServerRequestInterface $request): ResponseInterface
public function onRequest(ServerRequestInterface $request): ResponseInterface
{
$paths = explode("/",trim($request->getUri()->getPath(),"/"));

View File

@ -14,6 +14,34 @@ class Collection
{
}
public function deleteKey(string $key): void
{
$this->loadKeys();
if (!array_key_exists($key, $this->keys)) return;
$this->db->prepare("DELETE FROM vals WHERE key_id=:id")
->execute([ 'id' => $this->keys[$key] ]);
$this->db->prepare("DELETE FROM keys WHERE id=:id")
->execute([ 'id' => $this->keys[$key] ]);
}
public function deleteKeyValue(string $key, int $valueId): void
{
$this->loadKeys();
if (!array_key_exists($key, $this->keys)) return;
$this->db->prepare("DELETE FROM vals WHERE key_id=:id AND id=:valueid")
->execute([ 'id' => $this->keys[$key], 'valueid' => $valueId ]);
}
public function deleteValue(int $valueId): void
{
$this->db->prepare("DELETE FROM vals WHERE id=:valueid")
->execute([ 'valueid' => $valueId ]);
}
public function setValue(string $key, mixed $value, ?DateTime $validFrom = null, ?DateTime $validUntil = null, ?int $updateId = null)
{
// echo "setValue: {$key} = ".json_encode($value)."\n";
@ -90,12 +118,14 @@ class Collection
$valQuery = $this->db->prepare(
"SELECT * FROM vals WHERE ".
"key_id=:id AND (".
"(valid_from IS NULL) OR (datetime(valid_from) < datetime(:now)) AND ".
"(valid_until IS NULL) OR (datetime(valid_until) > datetime(:now))) ".
"((valid_from IS NULL) OR (datetime(valid_from) < datetime(:now))) AND ".
"((valid_until IS NULL) OR (datetime(valid_until) > datetime(:now)))) ".
"ORDER BY valid_from ASC");
$valQuery->execute([ "id" => $id, "now" => $when->format('Y-m-d H:i:sP') ]);
$valQuery->execute([ "id" => $id, "now" => $when->format('Y-m-d H:i:s P') ]);
$last = null;
while ($row = $valQuery->fetch(PDO::FETCH_ASSOC)) $last = $row;
while ($row = $valQuery->fetch(PDO::FETCH_ASSOC)) {
$last = $row;
}
if ($last)
$resolved[$key] = json_decode($last['value']);
}

View File

@ -5,5 +5,5 @@ require_once __DIR__."/../vendor/autoload.php";
define("APP_ROOT", dirname(__DIR__));
define("APP_DATA", APP_ROOT."/var");
$daemon = new NoccyLabs\ParamDb\Daemon();
$daemon = new NoccyLabs\ParamDb\Daemon(APP_DATA."/data.db");
$daemon->start();

View File

@ -2,15 +2,42 @@
namespace NoccyLabs\ParamDb;
use NoccyLabs\ParamDb\Storage\Collection;
use PHPUnit\Framework\Attributes\CoversClass;
use DateTime;
use React\Http\Message\ServerRequest;
#[CoversClass(Daemon::class)]
class DaemonTest extends \PHPUnit\Framework\TestCase
{
private Daemon $daemon;
public function setUp(): void
{
$this->daemon = new Daemon(":memory:");
$data = self::getTestValues();
$coll = $this->daemon->getDatabase()->createCollection("test");
$this->insertTestData($coll, $data);
}
public function testHandlingGetRequest()
{
$this->markTestSkipped();
$request = new ServerRequest("GET", "/test");
$response = $this->daemon->onRequest($request);
$this->assertEquals(200, $response->getStatusCode());
$resolved = json_decode($response->getBody()->getContents(), true);
$expect = [
'first' => 'c',
'second' => 'c',
];
$this->assertEquals($expect, $resolved);
}
public function testHandlingSetRequest()
@ -33,4 +60,26 @@ class DaemonTest extends \PHPUnit\Framework\TestCase
$this->markTestSkipped();
}
private function insertTestData(Collection $collection, array $data)
{
foreach ($data as [ $key, $value, $from, $until, $id ]) {
$collection->setValue($key, $value, $from, $until);
}
}
public static function getTestValues(): array
{
return [
// $key, $value, ?$from, ?$until, $expectedId
[ 'first', 'a', new DateTime("10 days ago 12:00:00"), new DateTime("9 days ago 12:00:00"), 1 ],
[ 'first', 'b', new DateTime("5 days ago 12:00:00"), new DateTime("4 days ago 12:00:00"), 2 ],
[ 'first', 'c', new DateTime("1 days ago 12:00:00"), new DateTime("1 days 12:00:00"), 3 ],
[ 'first', 'd', new DateTime("5 days 12:00:00"), new DateTime("6 days 12:00:00"), 4 ],
[ 'second', 'a', new DateTime("10 days ago 12:00:00"), new DateTime("9 days ago 12:00:00"), 5 ],
[ 'second', 'b', new DateTime("5 days ago 12:00:00"), new DateTime("4 days ago 12:00:00"), 6 ],
[ 'second', 'c', null, null, 7 ],
[ 'second', 'd', new DateTime("5 days"), new DateTime("6 days"), 8 ],
];
}
}

View File

@ -2,30 +2,180 @@
namespace NoccyLabs\ParamDb\Storage;
use DateTime;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
#[CoversClass(Collection::class)]
#[CoversClass(Database::class)]
class CollectionTest extends \PHPUnit\Framework\TestCase
{
private Database $db;
private Collection $coll;
public function setUp(): void
{
$this->db = new Database(":memory:");
$this->coll = $this->db->createCollection("foo");
$this->insertTestData($this->coll, self::getTestValues());
}
public function testInsertingValues()
{
$this->markTestSkipped();
$this->coll->setValue('third', 'c');
$resolved = $this->coll->resolveValues();
$expect = [
'first' => 'c',
'second' => 'c',
'third' => 'c',
];
$this->assertEquals($expect, $resolved);
$this->coll->setValue('third', 'd', new DateTime("5 days"), new DateTime("6 days"));
$resolved = $this->coll->resolveValues();
$this->assertEquals($expect, $resolved);
$this->coll->setValue('third', 'b', new DateTime("5 days ago"), new DateTime("4 days ago"));
$resolved = $this->coll->resolveValues();
$this->assertEquals($expect, $resolved);
}
public function testUpdatingValues()
{
$this->coll->setValue('third', 'c');
$resolved = $this->coll->resolveValues();
$expect = [
'first' => 'c',
'second' => 'c',
'third' => 'c',
];
$this->assertEquals($expect, $resolved);
$this->coll->setValue('third', 'd', new DateTime("5 days"), new DateTime("6 days"));
$resolved = $this->coll->resolveValues();
$this->assertEquals($expect, $resolved);
$this->coll->setValue('third', 'b', new DateTime("5 days ago"), new DateTime("4 days ago"));
$resolved = $this->coll->resolveValues();
$this->assertEquals($expect, $resolved);
}
public function testResolvingValues()
{
$this->markTestSkipped();
$resolved = $this->coll->resolveValues();
$expect = [
'first' => 'c',
'second' => 'c',
];
$this->assertEquals($expect, $resolved);
}
public function testProperSelectionOrderValues()
public function testGettingAllValues()
{
$this->markTestSkipped();
$resolved = $this->coll->getAllValues();
$values = self::getTestValuesSorted();
$expect = [];
foreach ($values as [$key,$value,$from,$until, $id]) {
if (!isset($expect[$key])) {
$expect[$key] = [];
}
if ($from && $until) {
$validity = [ 'validity' => [ 'from' => $from->format('Y-m-d H:i:s P'), 'until' => $until->format('Y-m-d H:i:s P') ]];
} elseif ($from) {
$validity = [ 'validity' => [ 'from' => $from->format('Y-m-d H:i:s P') ]];
} elseif ($until) {
$validity = [ 'validity' => [ 'until' => $until->format('Y-m-d H:i:s P') ]];
} else {
$validity = [];
}
$expect[$key][] = [ 'value' => $value, 'id' => $id, ...$validity ];
}
$this->assertEquals($expect, $resolved);
}
public function testDeletingValues()
{
$this->markTestSkipped();
$resolved = $this->coll->resolveValues();
$expect = [
'first' => 'c',
'second' => 'c',
];
$this->assertEquals($expect, $resolved);
$this->coll->deleteValue(5);
$resolved = $this->coll->resolveValues();
$this->assertEquals($expect, $resolved);
$this->coll->deleteValue(7);
$resolved = $this->coll->resolveValues();
$expect = [
'first' => 'c',
];
$this->assertEquals($expect, $resolved);
}
private function insertTestData(Collection $collection, array $data)
{
foreach ($data as [ $key, $value, $from, $until, $id ]) {
$collection->setValue($key, $value, $from, $until);
}
}
public static function getTestValues(): array
{
return [
// $key, $value, ?$from, ?$until, $expectedId
[ 'first', 'a', new DateTime("10 days ago 12:00:00"), new DateTime("9 days ago 12:00:00"), 1 ],
[ 'first', 'b', new DateTime("5 days ago 12:00:00"), new DateTime("4 days ago 12:00:00"), 2 ],
[ 'first', 'c', new DateTime("1 days ago 12:00:00"), new DateTime("1 days 12:00:00"), 3 ],
[ 'first', 'd', new DateTime("5 days 12:00:00"), new DateTime("6 days 12:00:00"), 4 ],
[ 'second', 'a', new DateTime("10 days ago 12:00:00"), new DateTime("9 days ago 12:00:00"), 5 ],
[ 'second', 'b', new DateTime("5 days ago 12:00:00"), new DateTime("4 days ago 12:00:00"), 6 ],
[ 'second', 'c', null, null, 7 ],
[ 'second', 'd', new DateTime("5 days"), new DateTime("6 days"), 8 ],
];
}
public static function getTestValuesSorted(): array
{
return [
// $key, $value, ?$from, ?$until, $expectedId
[ 'first', 'a', new DateTime("10 days ago 12:00:00"), new DateTime("9 days ago 12:00:00"), 1 ],
[ 'first', 'b', new DateTime("5 days ago 12:00:00"), new DateTime("4 days ago 12:00:00"), 2 ],
[ 'first', 'c', new DateTime("1 days ago 12:00:00"), new DateTime("1 days 12:00:00"), 3 ],
[ 'first', 'd', new DateTime("5 days 12:00:00"), new DateTime("6 days 12:00:00"), 4 ],
[ 'second', 'c', null, null, 7 ],
[ 'second', 'a', new DateTime("10 days ago 12:00:00"), new DateTime("9 days ago 12:00:00"), 5 ],
[ 'second', 'b', new DateTime("5 days ago 12:00:00"), new DateTime("4 days ago 12:00:00"), 6 ],
[ 'second', 'd', new DateTime("5 days"), new DateTime("6 days"), 8 ],
];
}
}

View File

@ -10,17 +10,26 @@ class DatabaseTest extends \PHPUnit\Framework\TestCase
public function testOpeningDatabases()
{
$this->markTestSkipped();
$database = new Database(":memory:");
$this->assertInstanceOf(Database::class, $database);
}
public function testCreatingCollections()
{
$this->markTestSkipped();
$database = new Database(":memory:");
$collection = $database->createCollection("test");
$this->assertInstanceOf(Collection::class, $collection);
}
public function testOpeningCollections()
{
$this->markTestSkipped();
$database = new Database(":memory:");
$collection = $database->createCollection("test");
$collection = $database->getCollection("test");
$this->assertInstanceOf(Collection::class, $collection);
}
public function testPurgingCollection()
@ -30,7 +39,10 @@ class DatabaseTest extends \PHPUnit\Framework\TestCase
public function testExceptionsIfCollectionNotExists()
{
$this->markTestSkipped();
$database = new Database(":memory:");
$this->expectException(\Exception::class);
$collection = $database->getCollection("test");
}
}