Skip to content

Commit b6bcc23

Browse files
committed
Add an Ascii exporter and its tests.
1 parent 8183ab1 commit b6bcc23

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed
+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace spec\drupol\phptree\Exporter;
6+
7+
use drupol\phptree\Exporter\Ascii;
8+
use drupol\phptree\Node\ValueNode;
9+
use PhpSpec\ObjectBehavior;
10+
11+
class AsciiSpec extends ObjectBehavior
12+
{
13+
public function it_is_initializable()
14+
{
15+
$this->shouldHaveType(Ascii::class);
16+
}
17+
18+
public function it_can_export_to_ascii()
19+
{
20+
$tree = new ValueNode('root', 2);
21+
22+
foreach (\range('A', 'Z') as $key => $value) {
23+
$nodes[$value] = new ValueNode($value, 2);
24+
}
25+
26+
$tree->add(...\array_values($nodes));
27+
28+
$expected = <<<EOF
29+
├─ root
30+
└─┐
31+
├─┐
32+
│ ├─ A
33+
│ └─┐
34+
│ ├─┐
35+
│ │ ├─ C
36+
│ │ └─┐
37+
│ │ ├─┐
38+
│ │ │ ├─ G
39+
│ │ │ └─┐
40+
│ │ │ ├─┐
41+
│ │ │ │ └─ O
42+
│ │ │ └─┐
43+
│ │ │ └─ P
44+
│ │ └─┐
45+
│ │ ├─ H
46+
│ │ └─┐
47+
│ │ ├─┐
48+
│ │ │ └─ Q
49+
│ │ └─┐
50+
│ │ └─ R
51+
│ └─┐
52+
│ ├─ D
53+
│ └─┐
54+
│ ├─┐
55+
│ │ ├─ I
56+
│ │ └─┐
57+
│ │ ├─┐
58+
│ │ │ └─ S
59+
│ │ └─┐
60+
│ │ └─ T
61+
│ └─┐
62+
│ ├─ J
63+
│ └─┐
64+
│ ├─┐
65+
│ │ └─ U
66+
│ └─┐
67+
│ └─ V
68+
└─┐
69+
├─ B
70+
└─┐
71+
├─┐
72+
│ ├─ E
73+
│ └─┐
74+
│ ├─┐
75+
│ │ ├─ K
76+
│ │ └─┐
77+
│ │ ├─┐
78+
│ │ │ └─ W
79+
│ │ └─┐
80+
│ │ └─ X
81+
│ └─┐
82+
│ ├─ L
83+
│ └─┐
84+
│ ├─┐
85+
│ │ └─ Y
86+
│ └─┐
87+
│ └─ Z
88+
└─┐
89+
├─ F
90+
└─┐
91+
├─┐
92+
│ └─ M
93+
└─┐
94+
└─ N
95+
96+
EOF;
97+
98+
$this
99+
->export($tree)
100+
->shouldReturn($expected);
101+
}
102+
}

src/Exporter/Ascii.php

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace drupol\phptree\Exporter;
6+
7+
use drupol\phptree\Node\ValueNodeInterface;
8+
9+
/**
10+
* Class Ascii
11+
*/
12+
class Ascii implements ExporterInterface
13+
{
14+
/**
15+
* {@inheritdoc}
16+
*/
17+
public function export(ValueNodeInterface $node): string
18+
{
19+
$tree = new \RecursiveTreeIterator(
20+
new \RecursiveArrayIterator(
21+
$this->doExportAsArray($node)
22+
),
23+
\RecursiveTreeIterator::BYPASS_KEY,
24+
\CachingIterator::CATCH_GET_CHILD,
25+
\RecursiveTreeIterator::SELF_FIRST
26+
);
27+
28+
$tree->setPrefixPart(\RecursiveTreeIterator::PREFIX_LEFT, '');
29+
$tree->setPrefixPart(\RecursiveTreeIterator::PREFIX_END_HAS_NEXT, '├─');
30+
$tree->setPrefixPart(\RecursiveTreeIterator::PREFIX_END_LAST, '└─');
31+
$tree->setPrefixPart(\RecursiveTreeIterator::PREFIX_RIGHT, '');
32+
$tree->setPrefixPart(\RecursiveTreeIterator::PREFIX_MID_LAST, ' ');
33+
$tree->setPrefixPart(\RecursiveTreeIterator::PREFIX_MID_HAS_NEXT, '');
34+
35+
$output = '';
36+
37+
foreach ($tree as $value) {
38+
$entry = ('Array' === $entry = $tree->getEntry()) ?
39+
'':
40+
' ' . $entry;
41+
42+
$output .= $tree->getPrefix() . $entry . $tree->getPostfix() . PHP_EOL;
43+
}
44+
45+
return $output;
46+
}
47+
48+
/**
49+
* Export the tree in an array.
50+
*
51+
* @return array
52+
* The tree exported into an array.
53+
*/
54+
private function doExportAsArray(ValueNodeInterface $node): array
55+
{
56+
$children = [];
57+
/** @var ValueNodeInterface $child */
58+
foreach ($node->children() as $child) {
59+
$children[] = $this->doExportAsArray($child);
60+
}
61+
62+
return [] === $children ?
63+
[$node->getValue()]:
64+
[$node->getValue(), $children];
65+
}
66+
}

0 commit comments

Comments
 (0)