<?php
declare(strict_types=1);
namespace Sabberworm\CSS\Tests\Unit\Comment;
use PHPUnit\Framework\Constraint\LogicalAnd;
use PHPUnit\Framework\Constraint\TraversableContains;
use PHPUnit\Framework\TestCase;
use Sabberworm\CSS\Comment\Comment;
use Sabberworm\CSS\Tests\Unit\Comment\Fixtures\ConcreteCommentContainer;
use TRegx\PhpUnit\DataProviders\DataProvider;
* @covers \Sabberworm\CSS\Comment\CommentContainer
*/
final class CommentContainerTest extends TestCase
{
* @var ConcreteCommentContainer
*/
private $subject;
protected function setUp(): void
{
$this->subject = new ConcreteCommentContainer();
}
* @test
*/
public function getCommentsInitiallyReturnsEmptyArray(): void
{
self::assertSame([], $this->subject->getComments());
}
* @return array<non-empty-string, array{0: list<Comment>}>
*/
public function provideCommentArray(): array
{
return [
'no comment' => [[]],
'one comment' => [[new Comment('Is this really a spoon?')]],
'two comments' => [
[
new Comment('I’m a teapot.'),
new Comment('I’m a cafetière.'),
],
],
];
}
* @test
*
* @param list<Comment> $comments
*
* @dataProvider provideCommentArray
*/
public function addCommentsOnVirginContainerAddsCommentsProvided(array $comments): void
{
$this->subject->addComments($comments);
self::assertSame($comments, $this->subject->getComments());
}
* @test
*
* @param list<Comment> $comments
*
* @dataProvider provideCommentArray
*/
public function addCommentsWithEmptyArrayKeepsOriginalCommentsUnchanged(array $comments): void
{
$this->subject->setComments($comments);
$this->subject->addComments([]);
self::assertSame($comments, $this->subject->getComments());
}
* @return array<non-empty-string, array{0: list<Comment>}>
*/
public function provideAlternativeCommentArray(): array
{
return [
'no comment' => [[]],
'one comment' => [[new Comment('Can I eat it with my hands?')]],
'two comments' => [
[
new Comment('I’m a beer barrel.'),
new Comment('I’m a vineyard.'),
],
],
];
}
* @return array<non-empty-string, array{0: non-empty-list<Comment>}>
*/
public function provideAlternativeNonemptyCommentArray(): array
{
$data = $this->provideAlternativeCommentArray();
unset($data['no comment']);
return $data;
}
* This provider crosses two comment arrays (0, 1 or 2 comments) with different comments,
* so that all combinations can be tested.
*
* @return DataProvider<non-empty-string, array{0: list<Comment>, 1: list<Comment>}>
*/
public function provideTwoDistinctCommentArrays(): DataProvider
{
return DataProvider::cross($this->provideCommentArray(), $this->provideAlternativeCommentArray());
}
* @return DataProvider<non-empty-string, array{0: list<Comment>, 1: non-empty-list<Comment>}>
*/
public function provideTwoDistinctCommentArraysWithSecondNonempty(): DataProvider
{
return DataProvider::cross($this->provideCommentArray(), $this->provideAlternativeNonemptyCommentArray());
}
private static function createContainsConstraint(Comment $comment): TraversableContains
{
return new TraversableContains($comment);
}
* @param non-empty-list<Comment> $comments
*
* @return non-empty-list<TraversableContains>
*/
private static function createContainsConstraints(array $comments): array
{
return \array_map([self::class, 'createContainsConstraint'], $comments);
}
* @test
*
* @param list<Comment> $commentsToAdd
* @param non-empty-list<Comment> $originalComments
*
* @dataProvider provideTwoDistinctCommentArraysWithSecondNonempty
*/
public function addCommentsKeepsOriginalComments(array $commentsToAdd, array $originalComments): void
{
$this->subject->setComments($originalComments);
$this->subject->addComments($commentsToAdd);
self::assertThat(
$this->subject->getComments(),
LogicalAnd::fromConstraints(...self::createContainsConstraints($originalComments))
);
}
* @test
*
* @param list<Comment> $originalComments
* @param non-empty-list<Comment> $commentsToAdd
*
* @dataProvider provideTwoDistinctCommentArraysWithSecondNonempty
*/
public function addCommentsAfterCommentsSetAddsCommentsProvided(array $originalComments, array $commentsToAdd): void
{
$this->subject->setComments($originalComments);
$this->subject->addComments($commentsToAdd);
self::assertThat(
$this->subject->getComments(),
LogicalAnd::fromConstraints(...self::createContainsConstraints($commentsToAdd))
);
}
* @test
*
* @param non-empty-list<Comment> $comments
*
* @dataProvider provideAlternativeNonemptyCommentArray
*/
public function addCommentsAppends(array $comments): void
{
$firstComment = new Comment('I must be first!');
$this->subject->setComments([$firstComment]);
$this->subject->addComments($comments);
$result = $this->subject->getComments();
self::assertNotEmpty($result);
self::assertSame($firstComment, $result[0]);
}
* @test
*
* @param list<Comment> $comments
*
* @dataProvider provideCommentArray
*/
public function setCommentsOnVirginContainerSetsCommentsProvided(array $comments): void
{
$this->subject->setComments($comments);
self::assertSame($comments, $this->subject->getComments());
}
* @test
*
* @param list<Comment> $originalComments
* @param list<Comment> $commentsToSet
*
* @dataProvider provideTwoDistinctCommentArrays
*/
public function setCommentsReplacesWithCommentsProvided(array $originalComments, array $commentsToSet): void
{
$this->subject->setComments($originalComments);
$this->subject->setComments($commentsToSet);
self::assertSame($commentsToSet, $this->subject->getComments());
}
}