Add persistence (with local db implementation)
This commit is contained in:
parent
6abb14b3bd
commit
1a0bbf1099
19 changed files with 441 additions and 29 deletions
2
.env
2
.env
|
@ -29,5 +29,5 @@ APP_SECRET=5ea76603566babff85ae4fa3e7d44071
|
|||
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
|
||||
# For a PostgreSQL database, use: "postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=11&charset=utf8"
|
||||
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
||||
DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7
|
||||
DATABASE_URL=sqlite:///%kernel.project_dir%/var/data.db
|
||||
###< doctrine/doctrine-bundle ###
|
||||
|
|
|
@ -3,3 +3,4 @@ KERNEL_CLASS='App\Kernel'
|
|||
APP_SECRET='$ecretf0rt3st'
|
||||
SYMFONY_DEPRECATIONS_HELPER=999999
|
||||
PANTHER_APP_ENV=panther
|
||||
DATABASE_URL=sqlite:///%kernel.project_dir%/var/test.db
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
"twig/twig": "^2.12|^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dama/doctrine-test-bundle": "^6.3",
|
||||
"symfony/browser-kit": "^5.1",
|
||||
"symfony/css-selector": "^5.1",
|
||||
"symfony/debug-bundle": "^5.1",
|
||||
|
|
59
composer.lock
generated
59
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "42c5e66445821e40a4194fe5a0a8a7b7",
|
||||
"content-hash": "a571222fe89b2d15a25ad09857c44cc6",
|
||||
"packages": [
|
||||
{
|
||||
"name": "composer/package-versions-deprecated",
|
||||
|
@ -7256,6 +7256,63 @@
|
|||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "dama/doctrine-test-bundle",
|
||||
"version": "v6.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dmaicher/doctrine-test-bundle.git",
|
||||
"reference": "a364cfee35acb7d37698c4749f7dd34d04646535"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dmaicher/doctrine-test-bundle/zipball/a364cfee35acb7d37698c4749f7dd34d04646535",
|
||||
"reference": "a364cfee35acb7d37698c4749f7dd34d04646535",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/dbal": "^2.9,>=2.9.3",
|
||||
"doctrine/doctrine-bundle": "^1.11 || ^2.0",
|
||||
"php": "^7.1",
|
||||
"symfony/framework-bundle": "^3.4 || ^4.3 || ^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||
"symfony/phpunit-bridge": "^4.3 || ^5.0",
|
||||
"symfony/yaml": "^3.4 || ^4.3 || ^5.0"
|
||||
},
|
||||
"type": "symfony-bundle",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "7.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DAMA\\DoctrineTestBundle\\": "src/DAMA/DoctrineTestBundle"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "David Maicher",
|
||||
"email": "mail@dmaicher.de"
|
||||
}
|
||||
],
|
||||
"description": "Symfony bundle to isolate doctrine database tests and improve test performance",
|
||||
"keywords": [
|
||||
"doctrine",
|
||||
"isolation",
|
||||
"performance",
|
||||
"symfony",
|
||||
"tests"
|
||||
],
|
||||
"time": "2020-09-04T05:50:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v4.10.2",
|
||||
|
|
|
@ -12,4 +12,5 @@ return [
|
|||
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
||||
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true],
|
||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||
DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
|
||||
];
|
||||
|
|
4
config/packages/test/dama_doctrine_test_bundle.yaml
Normal file
4
config/packages/test/dama_doctrine_test_bundle.yaml
Normal file
|
@ -0,0 +1,4 @@
|
|||
dama_doctrine_test:
|
||||
enable_static_connection: true
|
||||
enable_static_meta_data_cache: true
|
||||
enable_static_query_cache: true
|
31
migrations/Version20201020204121.php
Normal file
31
migrations/Version20201020204121.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20201020204121 extends AbstractMigration
|
||||
{
|
||||
public function getDescription() : string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema) : void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE TABLE entry (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, title VARCHAR(255) NOT NULL, start DATETIME NOT NULL, "end" DATETIME NOT NULL)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema) : void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('DROP TABLE entry');
|
||||
}
|
||||
}
|
|
@ -33,4 +33,8 @@
|
|||
<listeners>
|
||||
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
|
||||
</listeners>
|
||||
|
||||
<extensions>
|
||||
<extension class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension"/>
|
||||
</extensions>
|
||||
</phpunit>
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace App\Controller;
|
|||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use App\Persistence\Entries;
|
||||
use App\Service\ActiveEntry;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
@ -33,15 +34,24 @@ class TimeController extends AbstractController
|
|||
*/
|
||||
private $activeEntry;
|
||||
|
||||
public function __construct(ActiveEntry $activeEntry)
|
||||
{
|
||||
/**
|
||||
* @var Entries
|
||||
*/
|
||||
private $entries;
|
||||
|
||||
public function __construct(
|
||||
ActiveEntry $activeEntry,
|
||||
Entries $entries
|
||||
) {
|
||||
$this->activeEntry = $activeEntry;
|
||||
$this->entries = $entries;
|
||||
}
|
||||
|
||||
public function index(): Response
|
||||
{
|
||||
return $this->render('time/index.html.twig', [
|
||||
'entry' => $this->activeEntry->get(),
|
||||
'entries' => $this->entries->get(10),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,22 +21,37 @@ namespace App\Entity;
|
|||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity()
|
||||
*/
|
||||
class Entry
|
||||
{
|
||||
/**
|
||||
* @ORM\Id()
|
||||
* @ORM\GeneratedValue()
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(type="string", length=255)
|
||||
*/
|
||||
private $title = '';
|
||||
|
||||
/**
|
||||
* @var \DateTimeImmutable|null
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
private $start;
|
||||
|
||||
/**
|
||||
* @var \DateTimeImmutable|null
|
||||
* @ORM\Column(type="datetime")
|
||||
*/
|
||||
private $stop;
|
||||
private $end;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
|
@ -49,6 +64,20 @@ class Entry
|
|||
$this->title = $title;
|
||||
}
|
||||
|
||||
public static function fromPersistence(
|
||||
string $title,
|
||||
\DateTimeImmutable $start,
|
||||
\DateTimeImmutable $end
|
||||
): self {
|
||||
$entry = new static();
|
||||
|
||||
$entry->title = $title;
|
||||
$entry->start = $start;
|
||||
$entry->end = $end;
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
public function start(): void
|
||||
{
|
||||
$this->start = new \DateTimeImmutable();
|
||||
|
@ -57,7 +86,7 @@ class Entry
|
|||
|
||||
public function stop(): void
|
||||
{
|
||||
$this->stop = new \DateTimeImmutable();
|
||||
$this->end = new \DateTimeImmutable();
|
||||
$this->running = false;
|
||||
}
|
||||
|
||||
|
@ -70,4 +99,19 @@ class Entry
|
|||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function getBegan(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->start;
|
||||
}
|
||||
|
||||
public function getEnded(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->end;
|
||||
}
|
||||
|
||||
public function getDuration(): \DateInterval
|
||||
{
|
||||
return $this->start->diff($this->end);
|
||||
}
|
||||
}
|
||||
|
|
40
src/Persistence/Entries.php
Normal file
40
src/Persistence/Entries.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Persistence;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use App\Entity\Entry;
|
||||
|
||||
interface Entries
|
||||
{
|
||||
/**
|
||||
* Adds the given entry to the persistence.
|
||||
* Those entries don't have identifiers and are always new.
|
||||
*/
|
||||
public function add(Entry $entry): void;
|
||||
|
||||
/**
|
||||
* Get amount of recent entries from persistence.
|
||||
*
|
||||
* @return array<Entry>
|
||||
*/
|
||||
public function get(int $limit): array;
|
||||
}
|
71
src/Persistence/LocalDatabase.php
Normal file
71
src/Persistence/LocalDatabase.php
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace App\Persistence;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use App\Entity\Entry;
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
class LocalDatabase implements Entries
|
||||
{
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
private $connection;
|
||||
|
||||
public function __construct(
|
||||
Connection $connection
|
||||
) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
public function add(Entry $entry): void
|
||||
{
|
||||
$this->connection->insert('entry', [
|
||||
'title' => $entry->getTitle(),
|
||||
'start' => $entry->getBegan()->format('U'),
|
||||
'end' => $entry->getEnded()->format('U'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function get(int $limit): array
|
||||
{
|
||||
$queryBuilder = $this->connection->createQueryBuilder();
|
||||
|
||||
$queryBuilder->select('*');
|
||||
$queryBuilder->from('entry');
|
||||
$queryBuilder->setMaxResults($limit);
|
||||
$queryBuilder->orderBy('id', 'desc');
|
||||
|
||||
$entries = [];
|
||||
|
||||
$result = $queryBuilder->execute();
|
||||
while ($entry = $result->fetch()) {
|
||||
$entries[] = Entry::fromPersistence(
|
||||
$entry['title'],
|
||||
new \DateTimeImmutable('@' . $entry['start']),
|
||||
new \DateTimeImmutable('@' . $entry['end'])
|
||||
);
|
||||
}
|
||||
|
||||
return $entries;
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ namespace App\Service;
|
|||
*/
|
||||
|
||||
use App\Entity\Entry;
|
||||
use App\Persistence\Entries;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
|
||||
class ActiveEntry
|
||||
|
@ -31,9 +32,17 @@ class ActiveEntry
|
|||
*/
|
||||
private $session;
|
||||
|
||||
public function __construct(SessionInterface $session)
|
||||
{
|
||||
/**
|
||||
* @var Entries
|
||||
*/
|
||||
private $persistence;
|
||||
|
||||
public function __construct(
|
||||
SessionInterface $session,
|
||||
Entries $persistence
|
||||
) {
|
||||
$this->session = $session;
|
||||
$this->persistence = $persistence;
|
||||
}
|
||||
|
||||
public function startNew(
|
||||
|
@ -51,7 +60,12 @@ class ActiveEntry
|
|||
|
||||
public function stopRunning(): void
|
||||
{
|
||||
$this->get()->stop();
|
||||
$entry = $this->get();
|
||||
|
||||
$entry->stop();
|
||||
|
||||
$this->persistence->add($entry);
|
||||
|
||||
$this->session->remove('runningEntry');
|
||||
}
|
||||
|
||||
|
|
12
symfony.lock
12
symfony.lock
|
@ -2,6 +2,18 @@
|
|||
"composer/package-versions-deprecated": {
|
||||
"version": "1.11.99"
|
||||
},
|
||||
"dama/doctrine-test-bundle": {
|
||||
"version": "4.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes-contrib",
|
||||
"branch": "master",
|
||||
"version": "4.0",
|
||||
"ref": "56eaa387b5e48ebcc7c95a893b47dfa1ad51449c"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/test/dama_doctrine_test_bundle.yaml"
|
||||
]
|
||||
},
|
||||
"doctrine/annotations": {
|
||||
"version": "1.0",
|
||||
"recipe": {
|
||||
|
|
12
templates/time/entries.html.twig
Normal file
12
templates/time/entries.html.twig
Normal file
|
@ -0,0 +1,12 @@
|
|||
<section>
|
||||
{% for entry in entries %}
|
||||
<article>
|
||||
<header>{{ entry.title }}</header>
|
||||
<time>{{ entry.began|date('d.m.Y') }}</time>
|
||||
<time>{{ entry.ended|date('H:i:s') }}</time>
|
||||
-
|
||||
<time>{{ entry.ended|date('H:i:s') }}</time>
|
||||
<!-- // TODO: Add duration, e.g. by using a view model -->
|
||||
</article>
|
||||
{% endfor %}
|
||||
</section>
|
|
@ -4,4 +4,5 @@
|
|||
<h1>Time entries</h1>
|
||||
|
||||
{{ include('time/timer.html.twig') }}
|
||||
{{ include('time/entries.html.twig') }}
|
||||
{% endblock %}
|
||||
|
|
|
@ -25,6 +25,7 @@ use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
|||
|
||||
/**
|
||||
* @covers App\Controller\TimeController
|
||||
* @covers App\Persistence\LocalDatabase
|
||||
* @uses App\Entity\Entry
|
||||
* @uses App\Service\ActiveEntry
|
||||
*/
|
||||
|
@ -33,7 +34,7 @@ class TimeControllerTest extends WebTestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function rootCanBeOpened()
|
||||
public function rootCanBeOpened(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
$crawler = $client->request('GET', '/');
|
||||
|
@ -45,7 +46,7 @@ class TimeControllerTest extends WebTestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function newEntryCanBeStarted()
|
||||
public function newEntryCanBeStarted(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
|
||||
|
@ -62,7 +63,7 @@ class TimeControllerTest extends WebTestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function runningEntryCanBeStopped()
|
||||
public function runningEntryCanBeStopped(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
|
||||
|
@ -83,7 +84,7 @@ class TimeControllerTest extends WebTestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function noneRunningEntryCanBeStopped()
|
||||
public function noneRunningEntryCanBeStopped(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
|
||||
|
@ -95,4 +96,26 @@ class TimeControllerTest extends WebTestCase
|
|||
$this->assertInputValueSame('title', '');
|
||||
$this->assertSelectorTextSame('button', 'Start');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function previousEntriesAreShownOnIndex(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
|
||||
$client->request('GET', '/');
|
||||
$client->submitForm('Start', ['title' => 'Test Entry 1']);
|
||||
$client->request('GET', '/');
|
||||
$client->submitForm('Stop');
|
||||
|
||||
$client->request('GET', '/');
|
||||
$client->submitForm('Start', ['title' => 'Test Entry 2']);
|
||||
$client->request('GET', '/');
|
||||
$client->submitForm('Stop');
|
||||
|
||||
$crawler = $client->request('GET', '/');
|
||||
$this->assertSelectorTextContains('article:nth-of-type(1)', 'Test Entry 2');
|
||||
$this->assertSelectorTextContains('article:nth-of-type(2)', 'Test Entry 1');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ class EntryTest extends TestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function canBeCreated()
|
||||
public function canBeCreatedViaConstructor(): void
|
||||
{
|
||||
$subject = new Entry();
|
||||
|
||||
|
@ -42,7 +42,25 @@ class EntryTest extends TestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function canBeCreatedWithTitle()
|
||||
public function canBeCreatedFromPersistence(): void
|
||||
{
|
||||
$subject = Entry::fromPersistence(
|
||||
'Example Title',
|
||||
new \DateTimeImmutable('2020-10-29 17:10:05'),
|
||||
new \DateTimeImmutable('2020-10-29 18:12:15')
|
||||
);
|
||||
|
||||
static::assertInstanceOf(Entry::class, $subject);
|
||||
static::assertSame('Example Title', $subject->getTitle());
|
||||
static::assertSame('2020-10-29 17:10:05', $subject->getBegan()->format('Y-m-d H:i:s'));
|
||||
static::assertSame('2020-10-29 18:12:15', $subject->getEnded()->format('Y-m-d H:i:s'));
|
||||
static::assertSame('01:02:10', $subject->getDuration()->format('%r%H:%I:%S'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function canBeCreatedWithTitle(): void
|
||||
{
|
||||
$subject = new Entry('Example title');
|
||||
|
||||
|
@ -52,7 +70,7 @@ class EntryTest extends TestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsProvidedTitle()
|
||||
public function returnsProvidedTitle(): void
|
||||
{
|
||||
$subject = new Entry('Example title');
|
||||
|
||||
|
@ -62,7 +80,7 @@ class EntryTest extends TestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function canBeStarted()
|
||||
public function canBeStarted(): void
|
||||
{
|
||||
$subject = new Entry();
|
||||
|
||||
|
@ -74,7 +92,7 @@ class EntryTest extends TestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function canBeStopped()
|
||||
public function canBeStopped(): void
|
||||
{
|
||||
$subject = new Entry();
|
||||
|
||||
|
@ -87,7 +105,7 @@ class EntryTest extends TestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function canBeStoppedEvenIfNotRunning()
|
||||
public function canBeStoppedEvenIfNotRunning(): void
|
||||
{
|
||||
$subject = new Entry();
|
||||
|
||||
|
@ -95,4 +113,59 @@ class EntryTest extends TestCase
|
|||
|
||||
static::assertFalse($subject->isRunning());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsNullForBeganBeforeStarted(): void
|
||||
{
|
||||
$subject = new Entry();
|
||||
|
||||
static::assertNull($subject->getBegan());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsBeganAfterStarted(): void
|
||||
{
|
||||
$subject = new Entry();
|
||||
$subject->start();
|
||||
|
||||
static::assertInstanceOf(\DateTimeImmutable::class, $subject->getBegan());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsNullForEndedBeforeStarted(): void
|
||||
{
|
||||
$subject = new Entry();
|
||||
|
||||
static::assertNull($subject->getEnded());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsEndedAfterStoped(): void
|
||||
{
|
||||
$subject = new Entry();
|
||||
$subject->start();
|
||||
$subject->stop();
|
||||
|
||||
static::assertInstanceOf(\DateTimeImmutable::class, $subject->getEnded());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsDurationAfterStopped(): void
|
||||
{
|
||||
$subject = new Entry();
|
||||
$subject->start();
|
||||
$subject->stop();
|
||||
|
||||
static::assertInstanceOf(\DateInterval::class, $subject->getDuration());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,12 +22,14 @@ namespace App\Tests\Service;
|
|||
*/
|
||||
|
||||
use App\Entity\Entry;
|
||||
use App\Persistence\Entries;
|
||||
use App\Service\ActiveEntry;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @covers App\Service\ActiveEntry
|
||||
*/
|
||||
|
@ -36,11 +38,13 @@ class ActiveEntryTest extends TestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function canBeCreated()
|
||||
public function canBeCreated(): void
|
||||
{
|
||||
$session = $this->prophesize(SessionInterface::class);
|
||||
$persistence = $this->prophesize(Entries::class);
|
||||
$subject = new ActiveEntry(
|
||||
$session->reveal()
|
||||
$session->reveal(),
|
||||
$persistence->reveal()
|
||||
);
|
||||
|
||||
static::assertInstanceOf(ActiveEntry::class, $subject);
|
||||
|
@ -49,11 +53,13 @@ class ActiveEntryTest extends TestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsEmptyEntryAsDefault()
|
||||
public function returnsEmptyEntryAsDefault(): void
|
||||
{
|
||||
$session = $this->prophesize(SessionInterface::class);
|
||||
$persistence = $this->prophesize(Entries::class);
|
||||
$subject = new ActiveEntry(
|
||||
$session->reveal()
|
||||
$session->reveal(),
|
||||
$persistence->reveal()
|
||||
);
|
||||
|
||||
$entry = $subject->get();
|
||||
|
@ -66,11 +72,13 @@ class ActiveEntryTest extends TestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function canStartANewEntry()
|
||||
public function canStartANewEntry(): void
|
||||
{
|
||||
$session = $this->prophesize(SessionInterface::class);
|
||||
$persistence = $this->prophesize(Entries::class);
|
||||
$subject = new ActiveEntry(
|
||||
$session->reveal()
|
||||
$session->reveal(),
|
||||
$persistence->reveal()
|
||||
);
|
||||
|
||||
$subject->startNew('Example title');
|
||||
|
@ -85,12 +93,14 @@ class ActiveEntryTest extends TestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsStartedEntry()
|
||||
public function returnsStartedEntry(): void
|
||||
{
|
||||
$session = $this->prophesize(SessionInterface::class);
|
||||
$persistence = $this->prophesize(Entries::class);
|
||||
$entry = $this->prophesize(Entry::class);
|
||||
$subject = new ActiveEntry(
|
||||
$session->reveal()
|
||||
$session->reveal(),
|
||||
$persistence->reveal()
|
||||
);
|
||||
|
||||
$session->set('runningEntry', Argument::type(Entry::class))->shouldBeCalled();
|
||||
|
@ -104,12 +114,14 @@ class ActiveEntryTest extends TestCase
|
|||
/**
|
||||
* @test
|
||||
*/
|
||||
public function stopsRunningEntry()
|
||||
public function stopsRunningEntry(): void
|
||||
{
|
||||
$session = $this->prophesize(SessionInterface::class);
|
||||
$persistence = $this->prophesize(Entries::class);
|
||||
$entry = $this->prophesize(Entry::class);
|
||||
$subject = new ActiveEntry(
|
||||
$session->reveal()
|
||||
$session->reveal(),
|
||||
$persistence->reveal()
|
||||
);
|
||||
|
||||
$session->set('runningEntry', Argument::type(Entry::class))->shouldBeCalled();
|
||||
|
@ -119,5 +131,6 @@ class ActiveEntryTest extends TestCase
|
|||
$subject->stopRunning();
|
||||
|
||||
$session->remove('runningEntry')->shouldBeCalled();
|
||||
$persistence->add($entry->reveal())->shouldBeCalled();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue