complete test coverage

This commit is contained in:
Joby 2022-12-13 12:29:14 -07:00
parent bc5991fdaa
commit 44a06ef9fb
4 changed files with 154 additions and 10 deletions

View file

@ -29,15 +29,16 @@ class ContainerGroup implements ContainerInterface, NodeInterface
protected $limit = 0;
/**
* @param int $limit
* @return ContainerGroup<NodeInterface>
*/
public static function catchAll(): ContainerGroup
public static function catchAll(int $limit = 0): ContainerGroup
{
return new ContainerGroup(
function () {
return true;
},
0
$limit
);
}
@ -78,32 +79,32 @@ class ContainerGroup implements ContainerInterface, NodeInterface
public function addChild(NodeInterface|Stringable|string $child, bool $prepend = false, bool $skip_sanitize = false): static
{
if ($this->willAccept($child)) {
$this->makeRoomForChild($prepend);
if ($this->willAccept($child, false)) {
$this->doAddChild($child, $prepend, $skip_sanitize);
$this->enforceChildLimit($prepend);
}
return $this;
}
public function addChildAfter(NodeInterface|Stringable|string $new_child, NodeInterface|Stringable|string $after_child, bool $skip_sanitize = false): static
{
if ($this->willAccept($new_child)) {
$this->makeRoomForChild(false);
if ($this->willAccept($new_child, false)) {
$this->doAddChildAfter($new_child, $after_child, $skip_sanitize);
$this->enforceChildLimit(false);
}
return $this;
}
public function addChildBefore(NodeInterface|Stringable|string $new_child, NodeInterface|Stringable|string $before_child, bool $skip_sanitize = false): static
{
if ($this->willAccept($new_child)) {
$this->makeRoomForChild(true);
if ($this->willAccept($new_child, false)) {
$this->doAddChildBefore($new_child, $before_child, $skip_sanitize);
$this->enforceChildLimit(true);
}
return $this;
}
protected function makeRoomForChild(bool $remove_from_end): void
protected function enforceChildLimit(bool $remove_from_end): void
{
if ($this->limit > 0) {
while (count($this->children) > $this->limit) {

View file

@ -9,7 +9,7 @@ use ByJoby\HTML\Tags\AbstractContentTag;
class ScriptTag extends AbstractContentTag implements MetadataContent, PhrasingContent, DisplayNone
{
const TAG = 'noscript';
const TAG = 'script';
public function setAsync(bool $async): static
{

View file

@ -2,6 +2,10 @@
namespace ByJoby\HTML\Containers;
use ByJoby\HTML\Html5\Tags\LinkTag;
use ByJoby\HTML\Html5\Tags\ScriptTag;
use ByJoby\HTML\Nodes\Comment;
use ByJoby\HTML\Nodes\Text;
use PHPUnit\Framework\TestCase;
class ContainerGroupTest extends TestCase
@ -19,4 +23,33 @@ class ContainerGroupTest extends TestCase
});
$this->assertFalse($group->willAccept('Foo'));
}
public function testOfTag()
{
$group = ContainerGroup::ofTag('script');
$this->assertTrue($group->willAccept(new ScriptTag));
$this->assertFalse($group->willAccept(new LinkTag));
$this->assertFalse($group->willAccept(new Comment('comment')));
$this->assertFalse($group->willAccept(new Text('comment')));
}
public function testLimits()
{
$group = ContainerGroup::catchAll(2);
$group->addChild('a');
$group->addChild('b');
$this->assertEquals('a' . PHP_EOL . 'b', $group->__toString());
// appending a child drops the first one
$group->addChild('c');
$this->assertEquals('b' . PHP_EOL . 'c', $group->__toString());
// prepending a child drops the last one
$group->addChild('d', true);
$this->assertEquals('d' . PHP_EOL . 'b', $group->__toString());
// adding a child before another drops the last child
$group->addChildBefore('e', 'b');
$this->assertEquals('d' . PHP_EOL . 'e', $group->__toString());
// adding a child after another drops the first child
$group->addChildAfter('f', 'e');
$this->assertEquals('e' . PHP_EOL . 'f', $group->__toString());
}
}

View file

@ -0,0 +1,110 @@
<?php
namespace ByJoby\HTML\Containers;
use ByJoby\HTML\Html5\Tags\BaseTag;
use ByJoby\HTML\Html5\Tags\LinkTag;
use ByJoby\HTML\Html5\Tags\ScriptTag;
use ByJoby\HTML\Html5\Tags\StyleTag;
use ByJoby\HTML\Nodes\Comment;
use PHPUnit\Framework\TestCase;
class GroupedContainerTest extends TestCase
{
public function testGroupedContainerBasicFunctions()
{
$container = new GroupedContainer();
$script = new ScriptTag;
$style = new StyleTag;
$link = new LinkTag;
$base = new BaseTag;
// initially accepts nothing
$this->assertFalse($container->willAccept($script));
$this->assertFalse($container->willAccept($style));
$this->assertFalse($container->willAccept($link));
$this->assertFalse($container->willAccept($base));
// also ensure none of these accept non-tag node
$this->assertFalse($container->willAccept(new Comment('test comment')));
// add group to hold style tags
$container->addGroup($styleGroup = ContainerGroup::ofTag('style'));
$this->assertFalse($container->willAccept($script));
$this->assertTrue($container->willAccept($style));
$this->assertFalse($container->willAccept($link));
$this->assertFalse($container->willAccept($base));
// add group to hold link tags by class
$container->addGroupBefore($linkGroup = ContainerGroup::ofClass(LinkTag::class), $styleGroup);
$this->assertFalse($container->willAccept($script));
$this->assertTrue($container->willAccept($style));
$this->assertTrue($container->willAccept($link));
$this->assertFalse($container->willAccept($base));
// add group to hold script tags by class
$container->addGroupAfter($scriptGroup = ContainerGroup::ofClass(ScriptTag::class), $styleGroup);
$this->assertTrue($container->willAccept($script));
$this->assertTrue($container->willAccept($style));
$this->assertTrue($container->willAccept($link));
$this->assertFalse($container->willAccept($base));
// add catch-all group
$container->addGroup($catchAll = ContainerGroup::catchAll());
$this->assertTrue($container->willAccept($script));
$this->assertTrue($container->willAccept($style));
$this->assertTrue($container->willAccept($link));
$this->assertTrue($container->willAccept($base));
// add script tag
$container->addChild($script);
$this->assertEquals($script->__toString(), $container->__toString());
// add style tag (it's before the style tag)
$container->addChild($style);
$this->assertEquals(
implode(PHP_EOL, [
$style->__toString(),
$script->__toString(),
]),
$container->__toString()
);
// add link tag (it's after the style tag)
$container->addChild($link);
$this->assertEquals(
implode(PHP_EOL, [
$link->__toString(),
$style->__toString(),
$script->__toString(),
]),
$container->__toString()
);
// add base (it's at the beginning)
$container->addChild($base);
$this->assertEquals(
implode(PHP_EOL, [
$link->__toString(),
$style->__toString(),
$script->__toString(),
$base->__toString(),
]),
$container->__toString()
);
}
public function testContains()
{
$container = new GroupedContainer();
$this->assertFalse($container->contains('a'));
$container->addGroup(ContainerGroup::catchAll());
$container->addChild('a');
$this->assertTrue($container->contains('a'));
$container->addChild($script = new ScriptTag);
$this->assertTrue($container->contains($script));
}
public function testAddAndRemoveChild()
{
$container = new GroupedContainer();
$container->addGroup(ContainerGroup::catchAll());
$container->addChild('a');
$container->addChildBefore('b', 'a');
$container->addChildAfter('c', 'b');
$this->assertEquals(implode(PHP_EOL, ['b', 'c', 'a']), $container->__toString());
// remove child c
$container->removeChild('c');
$this->assertEquals(implode(PHP_EOL, ['b', 'a']), $container->__toString());
}
}