Skip to content

Commit

Permalink
add new helpers to the config
Browse files Browse the repository at this point in the history
  • Loading branch information
efureev committed Apr 30, 2021
1 parent d92be53 commit 3ffb5fb
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 8 deletions.
11 changes: 7 additions & 4 deletions src/Config/AbstractAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
namespace Fureev\Trees\Config;

use Fureev\Trees\Exceptions\Exception;
use Php\Support\Traits\Maker;

/**
* Class AbstractAttribute
* @package Fureev\Trees\Config
*/
abstract class AbstractAttribute
{
use Maker;

protected string $name;

protected string $type = 'unsignedInteger';
Expand All @@ -21,10 +24,10 @@ abstract class AbstractAttribute
*/
protected $default;

public function __construct(string $name = null)
public function __construct(string $type = null)
{
if ($name) {
$this->name = $name;
if ($type) {
$this->setType($type);
}
}

Expand All @@ -50,7 +53,7 @@ public function setType(string $type): self
{
$typeOpt = Base::getCastForCustomAttribute($type);
if ($typeOpt === null) {
throw Exception::make("Invalid type {$type}");
throw Exception::make("Invalid type $type");
}

$this->type = $typeOpt;
Expand Down
12 changes: 11 additions & 1 deletion src/Config/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
use Fureev\Trees\Exceptions\Exception;
use Fureev\Trees\NestedSetTrait;
use Illuminate\Database\Eloquent\Model;
use Php\Support\Traits\Maker;

class Base implements NestedSetConfig
{
use Maker;

public const OPERATION_MAKE_ROOT = 1;
public const OPERATION_PREPEND_TO = 2;
public const OPERATION_APPEND_TO = 3;
Expand Down Expand Up @@ -88,6 +91,13 @@ public function setAttribute(string $name, AbstractAttribute $attribute): self
return $this;
}

public function setAttributeTree(TreeAttribute $attribute): self
{
$this->tree = $attribute;

return $this;
}

/**
* Get a list of default columns.
*
Expand Down Expand Up @@ -201,7 +211,7 @@ public function getCastForTreeAttribute(): ?string
*
* @return mixed
*/
public function generateTreeId(Model $model)
public function generateTreeId(Model $model): mixed
{
if (method_exists($model, 'generateTreeId')) {
return $model->generateTreeId();
Expand Down
4 changes: 2 additions & 2 deletions tests/Unit/AbstractUnitTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ static function (Blueprint $table) use ($config, $model, $connectionDriver) {


if (in_array($model->getKeyType(), ['uuid', 'string'])) {
$table->uuid('id')->default($expression)->primary();
$table->uuid($model->getKeyName())->default($expression)->primary();
} else {
$table->integerIncrements('id');
$table->integerIncrements($model->getKeyName());
}

Migrate::columns($table, $config);
Expand Down
210 changes: 210 additions & 0 deletions tests/Unit/CollectionCustomModelTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
<?php

namespace Fureev\Trees\Tests\Unit;

use Fureev\Trees\Collection;
use Fureev\Trees\Tests\models\CustomModel;

class CollectionCustomModelTest extends AbstractUnitTestCase
{

/** @var CustomModel|string */
protected static $modelClass = CustomModel::class;

public function testLinkNodes(): void
{
$childrenTree = [2, 3, 2, 3];
static::makeTree(null, ...$childrenTree);

$preQueryCount = count((new static::$modelClass)->getConnection()->getQueryLog());
$expectedQueryCount = $preQueryCount + 2;
/** @var CustomModel $root */
$root = static::$modelClass::root()->first();

static::assertTrue($root->treeAttribute()->name() === static::$modelClass::TREE_ID);
static::assertTrue($root->parentAttribute()->name() === static::$modelClass::PARENT_ID);
static::assertTrue($root->leftAttribute()->name() === 'left_offset');
static::assertTrue($root->rightAttribute()->name() === 'right_offset');
static::assertTrue($root->levelAttribute()->name() === 'deeeeep');

$collection = static::$modelClass::byTree($root->treeValue())->get();

$collection->linkNodes();

/** @var CustomModel $root */
$root = $collection->where('parent_id', '=', null)->first();

static::assertCount($expectedQueryCount, $root->getConnection()->getQueryLog());

static::assertCount(3, $root->children);
static::assertNull($root->parent);
static::assertCount($expectedQueryCount, $root->getConnection()->getQueryLog());

foreach ($root->children as $children1) {
static::assertCount(2, $children1->children);
static::assertTrue($root->equalTo($children1->parent));

foreach ($children1->children as $children2) {
static::assertCount(3, $children2->children);
static::assertTrue($children1->equalTo($children2->parent));
}
}

static::assertCount($expectedQueryCount, $root->getConnection()->getQueryLog());
}

public function testWoLinkNodes(): void
{
$childrenTree = [2, 3, 2, 3];
static::makeTree(null, ...$childrenTree);

$preQueryCount = count((new static::$modelClass)->getConnection()->getQueryLog());
$expectedQueryCount = $preQueryCount + 2;

$root = static::$modelClass::root()->first();
$collection = static::$modelClass::byTree($root->treeValue())->get();

/** @var CustomModel $root */
$root = $collection->where('parent_id', '=', null)->first();

static::assertCount($expectedQueryCount, $root->getConnection()->getQueryLog());

static::assertCount(3, $root->children);
static::assertNull($root->parent);
static::assertCount($expectedQueryCount + 1, $root->getConnection()->getQueryLog());

foreach ($root->children as $children1) {
static::assertCount(2, $children1->children);
static::assertTrue($root->equalTo($children1->parent));
}

static::assertCount($expectedQueryCount + 7, $root->getConnection()->getQueryLog());
}

public function testToTreeWithRootNode(): void
{
$childrenNodesMap = [2, 3, 2, 3];
static::makeTree(null, ...$childrenNodesMap);

$preQueryCount = count((new static::$modelClass)->getConnection()->getQueryLog());
$expectedQueryCount = $preQueryCount + 2;

$root = static::$modelClass::root()->first();
$list = static::$modelClass::byTree($root->treeValue())->get();

static::assertCount(static::sum($childrenNodesMap) / 2, $list);

/** @var CustomModel $root */
$root = $list->where('parent_id', '=', null)->first();

$tree = $list->toTree($root);

static::assertCount(3, $tree);
static::assertNull($root->parent);

foreach ($root->children as $children1) {
static::assertCount(2, $children1->children);
static::assertTrue($root->equalTo($children1->parent));
}

static::assertCount($expectedQueryCount + $root->children->count(), $root->getConnection()->getQueryLog());
}

public function testToTreeWithOutRootNode(): void
{
$childrenNodesMap = [2, 3];
static::makeTree(null, ...$childrenNodesMap);

$preQueryCount = count((new static::$modelClass)->getConnection()->getQueryLog());
$expectedQueryCount = $preQueryCount + 1;

$list = static::$modelClass::all();

static::assertCount(static::sum($childrenNodesMap), $list);

$tree = $list->toTree();

static::assertCount(2, $tree);


foreach ($tree as $page) {
static::assertCount(3, $page['children']);
}

static::assertCount($expectedQueryCount, $list->first()->getConnection()->getQueryLog());
}

public function testToTreeCustomLevels(): void
{
$childrenNodesMap = [2, 3, 1, 2];
static::makeTree(null, ...$childrenNodesMap);

foreach ($childrenNodesMap as $level => $childrenCount) {
$preQueryCount = count((new static::$modelClass)->getConnection()->getQueryLog());
$expectedQueryCount = $preQueryCount + 1;


$list = static::$modelClass::toLevel($level)->get();
static::assertCount(static::sum($childrenNodesMap, $level), $list);

static::assertEmpty($list->filter(function ($item) use ($level) {
return $item->levelValue() > $level;
}));

static::assertCount(static::sum($childrenNodesMap, $level), $list->filter(function ($item) use ($level) {
return $item->levelValue() <= $level;
}));

/** @var Collection $tree */
$tree = $list->toTree();

static::assertCount(2, $tree);

static::assertCount($expectedQueryCount, $list->first()->getConnection()->getQueryLog());
}
}

public function testToTreeArrayMultiRoots(): void
{
$childrenNodesMap = [5, 3, 2];
static::makeTree(null, ...$childrenNodesMap);

$preQueryCount = count((new static::$modelClass)->getConnection()->getQueryLog());
$expectedQueryCount = $preQueryCount + 1;

$list = static::$modelClass::all();

static::assertCount(static::sum($childrenNodesMap), $list);

$tree = $list->toTree()->toArray();

static::assertCount(5, $tree);


foreach ($tree as $pages) {
static::assertCount(3, $pages['children']);

foreach ($pages['children'] as $page) {
static::assertCount(2, $page['children']);
}
}

static::assertCount($expectedQueryCount, $list->first()->getConnection()->getQueryLog());
}

public function testGetRoots(): void
{
static::makeTree(null, 6, 1, 2, 1);

$list = static::$modelClass::all();
$expectedQueryCount = count((new static::$modelClass)->getConnection()->getQueryLog());

static::assertCount(36, $list);

$roots = $list->getRoots();

static::assertCount(6, $roots);

static::assertCount($expectedQueryCount, $list->first()->getConnection()->getQueryLog());
}
}
2 changes: 1 addition & 1 deletion tests/Unit/MigrateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function testMultiCustomGetColumns(): void
Migrate::columns(
$table,
new Config\Base(
(new Config\TreeAttribute('tid'))->setType('uuid')->setNullable()
(new Config\TreeAttribute('uuid'))->setName('tid')->setNullable()
)
);

Expand Down
51 changes: 51 additions & 0 deletions tests/models/CustomModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace Fureev\Trees\Tests\models;

use Fureev\Trees\Config\Base;
use Fureev\Trees\Config\LeftAttribute;
use Fureev\Trees\Config\LevelAttribute;
use Fureev\Trees\Config\ParentAttribute;
use Fureev\Trees\Config\RightAttribute;
use Fureev\Trees\Config\TreeAttribute;
use Ramsey\Uuid\Uuid;

/**
* Class Page
*
* @package Fureev\Trees\Tests\models
* @property string $id
* @property string $parent_id
*
* @mixin \Fureev\Trees\QueryBuilder
*/
class CustomModel extends BaseModel
{
public const TREE_ID = 'struct_id';
public const PARENT_ID = 'papa_id';

protected $keyType = 'string';

protected $primaryKey = 'num';

protected $table = 'pages_uuid';

protected $fillable = ['title', '_setRoot'];

protected $hidden = ['_setRoot', 'lft', 'rgt', 'lvl', 'struct_id', 'parent_id'];

protected static function buildTreeConfig(): Base
{
return Base::make()
->setAttributeTree(TreeAttribute::make('uuid')->setName(self::TREE_ID))
->setAttribute('parent', ParentAttribute::make()->setName(self::PARENT_ID))
->setAttribute('left', LeftAttribute::make()->setName('left_offset'))
->setAttribute('right', RightAttribute::make()->setName('right_offset'))
->setAttribute('level', LevelAttribute::make()->setName('deeeeep'));
}

public function generateTreeId(): string
{
return Uuid::uuid4()->toString();
}
}

0 comments on commit 3ffb5fb

Please sign in to comment.