Skip to content

Commit

Permalink
improved tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dakujem committed Jan 26, 2024
1 parent 01426c3 commit 36f229c
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 58 deletions.
60 changes: 22 additions & 38 deletions tests/iterators.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use Dakujem\Oliva\Iterator\Native;
use Dakujem\Oliva\Iterator\PostOrderTraversal;
use Dakujem\Oliva\Iterator\PreOrderTraversal;
use Dakujem\Oliva\Iterator\Support\Counter;
use Dakujem\Oliva\Node;
use Dakujem\Oliva\TreeNodeContract;
use RecursiveIteratorIterator;
use Tester\Assert;
Expand All @@ -25,75 +24,51 @@ require_once __DIR__ . '/setup.php';
Assert::same(2, $counter->current());
Assert::same(3, $counter->next());
Assert::same(3, $counter->current());
})();

(function () {
$counter = new Counter(5);
Assert::same(5, $counter->current());
})();


$a = new Node('A');
$b = new Node('B');
$c = new Node('C');
$d = new Node('D');
$e = new Node('E');
$f = new Node('F');
$g = new Node('G');
$h = new Node('H');
$i = new Node('I');

$edge = function (Node $from, Node $to): void {
$from->addChild($to);
$to->setParent($from);
};

// Tree from here:
// https://en.wikipedia.org/wiki/Tree_traversal
$root = $f;
$edge($f, $b);
$edge($b, $a);
$edge($b, $d);
$edge($d, $c);
$edge($d, $e);
$edge($f, $g);
$edge($g, $i);
$edge($i, $h);
(function () {
$root = Preset::wikiTree();

$iterator = new PreOrderTraversal($root);
$str = '';
foreach ($iterator as $node) {
$str .= $node->data();
}
//echo $str;
//echo "\n";
Assert::same('FBADCEGIH', $str);
Assert::same('FBADCEGIH', TreeTesterTool::append($iterator));

$iterator = new PostOrderTraversal($root);
$str = '';
foreach ($iterator as $node) {
$str .= $node->data();
}
//echo $str;
//echo "\n";
Assert::same('ACEDBHIGF', $str);
Assert::same('ACEDBHIGF', TreeTesterTool::append($iterator));

$iterator = new LevelOrderTraversal($root);
$str = '';
foreach ($iterator as $i => $node) {
$str .= $node->data();
}
//echo $str;
//echo "\n";
Assert::same('FBGADICEH', $str);
Assert::same('FBGADICEH', TreeTesterTool::append($iterator));

//echo "\n";
Assert::type(PreOrderTraversal::class, $root->getIterator());
$str = '';
foreach ($root as $node) {
$str .= $node->data();
}
//echo $str;
Assert::same('FBADCEGIH', $str);
//echo "\n";
Assert::same('FBADCEGIH', TreeTesterTool::append($root->getIterator()));
})();

(function () {
$root = Preset::wikiTree();

$iterator = new PreOrderTraversal(
node: $root,
Expand Down Expand Up @@ -166,7 +141,10 @@ require_once __DIR__ . '/setup.php';
'a.b.1.0.0' => 'H',
];
Assert::same($expected, array_map(fn(DataNodeContract $node) => $node->data(), iterator_to_array($iterator)));
})();

(function () {
$root = Preset::wikiTree();

$iterator = new PostOrderTraversal($root);
$expected = [
Expand Down Expand Up @@ -199,8 +177,10 @@ require_once __DIR__ . '/setup.php';
'a.b' => 'F',
];
Assert::same($expected, array_map(fn(DataNodeContract $node) => $node->data(), iterator_to_array($iterator)));
})();


(function () {
$root = Preset::wikiTree();

$iterator = new LevelOrderTraversal($root);
$expected = [
Expand Down Expand Up @@ -233,8 +213,12 @@ require_once __DIR__ . '/setup.php';
'a.b.1.0.0' => 'H',
];
Assert::same($expected, array_map(fn(DataNodeContract $node) => $node->data(), iterator_to_array($iterator)));
})();


(function () {
$root = Preset::wikiTree();

// level-order (?), leaves only (the default)
$str = [];
foreach (new RecursiveIteratorIterator(new Native($root)) as $node) {
Expand Down
15 changes: 4 additions & 11 deletions tests/nodes.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,10 @@ require_once __DIR__ . '/setup.php';
]);

// pre-order
$str = [];
foreach ($root as $node) {
$str[] = $node->data();
}
Assert::same('F,B,A,D,C,E,G,I,H', implode(',', $str));

Assert::same('FBADCEGIH', TreeTesterTool::flatten($root));
})();

(function () {
// Tree from here:
// https://en.wikipedia.org/wiki/Tree_traversal
$data = [
Expand Down Expand Up @@ -82,9 +79,5 @@ require_once __DIR__ . '/setup.php';
$root = $wrapper->wrap($data);

// pre-order
$str = [];
foreach ($root as $node) {
$str[] = $node->data();
}
Assert::same('F,B,A,D,C,E,G,I,H', implode(',', $str));
Assert::same('FBADCEGIH', TreeTesterTool::flatten($root));
})();
68 changes: 59 additions & 9 deletions tests/setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

use Dakujem\Oliva\DataNodeContract;
use Dakujem\Oliva\Iterator\PreOrderTraversal;
use Dakujem\Oliva\MovableNodeContract;
use Dakujem\Oliva\Node;
use Dakujem\Oliva\TreeNodeContract;
use Tester\Environment;

Expand All @@ -15,31 +17,79 @@

final class TreeTesterTool
{
public static function concatTree(
public static function flatten(
TreeNodeContract $node,
string $traversalClass = PreOrderTraversal::class,
string $delimiter = '',
string $glue = '',
): string {
return self::concat(
return self::append(
new $traversalClass($node),
$delimiter,
$glue,
);
}

public static function concat(iterable $traversal, string $delimiter = ''): string
{
public static function append(
iterable $traversal,
string $glue = '',
?callable $extractor = null,
): string {
$extractor ??= fn(DataNodeContract $item) => $item->data();
return self::reduce(
$traversal,
fn(string $carry, DataNodeContract $item) => $carry . $delimiter . $item->data(),
fn(string $carry, DataNodeContract $item) => $carry . $glue . $extractor($item),
);
}

public static function reduce(iterable $traversal, callable $reducer, string $carry = ''): string
{
public static function reduce(
iterable $traversal,
callable $reducer,
string $carry = '',
): string {
foreach ($traversal as $node) {
$carry = $reducer($carry, $node);
}
return $carry;
}
}

final class Manipulator
{
public static function edge(MovableNodeContract $parent, MovableNodeContract $child): void
{
$parent->addChild($child);
$child->setParent($parent);
}
}

final class Preset
{
/**
* Returns manually built tree from Wikipedia:
* @link https://en.wikipedia.org/wiki/Tree_traversal
*/
public static function wikiTree(): Node
{
$a = new Node('A');
$b = new Node('B');
$c = new Node('C');
$d = new Node('D');
$e = new Node('E');
$f = new Node('F');
$g = new Node('G');
$h = new Node('H');
$i = new Node('I');


$root = $f;
Manipulator::edge($f, $b);
Manipulator::edge($b, $a);
Manipulator::edge($b, $d);
Manipulator::edge($d, $c);
Manipulator::edge($d, $e);
Manipulator::edge($f, $g);
Manipulator::edge($g, $i);
Manipulator::edge($i, $h);

return $root;
}
}
46 changes: 46 additions & 0 deletions tests/tool.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Dakujem\Test;

use Dakujem\Oliva\Iterator\LevelOrderTraversal;
use Dakujem\Oliva\Iterator\PostOrderTraversal;
use Dakujem\Oliva\Iterator\PreOrderTraversal;
use Dakujem\Oliva\Node;
use Tester\Assert;

require_once __DIR__ . '/setup.php';


(function () {
$a = new Node('A');
$b = new Node('B');
Manipulator::edge($a, $b);
Assert::same($a, $b->parent());
Assert::same($b, $a->child(0));
})();

(function () {
Assert::same('', TreeTesterTool::append([]));
Assert::same('ABC', TreeTesterTool::append([
new Node('A'),
new Node('B'),
new Node('C'),
]));
Assert::same('', TreeTesterTool::append([], '.'));
Assert::same('.A.B.C', TreeTesterTool::append([
new Node('A'),
new Node('B'),
new Node('C'),
], '.'));
})();


(function () {
$tree = Preset::wikiTree();
Assert::same('FBADCEGIH', TreeTesterTool::flatten($tree));
Assert::same('FBADCEGIH', TreeTesterTool::flatten($tree, PreOrderTraversal::class));
Assert::same('ACEDBHIGF', TreeTesterTool::flatten($tree, PostOrderTraversal::class));
Assert::same('FBGADICEH', TreeTesterTool::flatten($tree, LevelOrderTraversal::class));
})();

0 comments on commit 36f229c

Please sign in to comment.