Skip to content

Commit 525486e

Browse files
authored
Merge pull request #132 from php-school/split-item-menu-tests
Split item menu tests
2 parents c4c0d51 + 39d5df7 commit 525486e

File tree

2 files changed

+417
-63
lines changed

2 files changed

+417
-63
lines changed

src/MenuItem/SplitItem.php

Lines changed: 81 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class SplitItem implements MenuItemInterface
1616
/**
1717
* @var array
1818
*/
19-
private $items;
19+
private $items = [];
2020

2121
/**
2222
* @var int|null
@@ -44,12 +44,11 @@ class SplitItem implements MenuItemInterface
4444

4545
public function __construct(array $items = [])
4646
{
47-
$this->items = $items;
48-
47+
$this->addItems($items);
4948
$this->setDefaultSelectedItem();
5049
}
5150

52-
public function addMenuItem(MenuItemInterface $item) : self
51+
public function addItem(MenuItemInterface $item) : self
5352
{
5453
foreach (self::$blacklistedItems as $bl) {
5554
if ($item instanceof $bl) {
@@ -61,18 +60,19 @@ public function addMenuItem(MenuItemInterface $item) : self
6160
return $this;
6261
}
6362

64-
public function addMenuItems(array $items) : self
63+
public function addItems(array $items) : self
6564
{
6665
foreach ($items as $item) {
67-
$this->addMenuItem($item);
66+
$this->addItem($item);
6867
}
68+
6969
return $this;
7070
}
71-
71+
7272
public function setItems(array $items) : self
7373
{
7474
$this->items = [];
75-
$this->addMenuItems($items);
75+
$this->addItems($items);
7676
return $this;
7777
}
7878

@@ -100,72 +100,90 @@ public function getRows(MenuStyle $style, bool $selected = false) : array
100100
{
101101
$numberOfItems = count($this->items);
102102

103+
if ($numberOfItems === 0) {
104+
throw new \RuntimeException(sprintf('There should be at least one item added to: %s', __CLASS__));
105+
}
106+
103107
if (!$selected) {
104108
$this->setDefaultSelectedItem();
105109
}
106110

107-
$length = $style->getDisplaysExtra()
108-
? floor(($style->getContentWidth() - mb_strlen($style->getItemExtra()) + 2) / $numberOfItems)
109-
: floor($style->getContentWidth() / $numberOfItems);
110-
111-
$length -= $this->margin;
112-
111+
$length = floor($style->getContentWidth() / $numberOfItems) - $this->margin;
113112
$missingLength = $style->getContentWidth() % $numberOfItems;
114-
115-
$cells = array_map(function ($index, $item) use ($selected, $length, $style) {
116-
$isSelected = $selected && $index === $this->selectedItemIndex;
117-
$marker = $item->canSelect()
118-
? sprintf("%s ", $style->getMarker($isSelected))
119-
: sprintf("%s ", str_repeat(' ', mb_strlen($style->getMarker(false))));
120-
$content = StringUtil::wordwrap(
121-
sprintf('%s%s', $marker, $item->getText()),
122-
$length
123-
);
124-
return array_map(function ($row) use ($length, $style, $isSelected) {
125-
$invertedColoursSetCode = $isSelected
126-
? $style->getInvertedColoursSetCode()
127-
: '';
128-
$invertedColoursUnsetCode = $isSelected
129-
? $style->getInvertedColoursUnsetCode()
113+
114+
return $this->buildRows(
115+
array_map(function ($index, $item) use ($selected, $length, $style) {
116+
$isSelected = $selected && $index === $this->selectedItemIndex;
117+
$marker = $item->canSelect()
118+
? sprintf('%s ', $style->getMarker($isSelected))
130119
: '';
131120

132-
return sprintf(
133-
"%s%s%s%s%s",
134-
$invertedColoursSetCode,
135-
$row,
136-
str_repeat(' ', $length - mb_strlen($row)),
137-
$invertedColoursUnsetCode,
138-
str_repeat(' ', $this->margin)
121+
return $this->buildCell(
122+
explode("\n", StringUtil::wordwrap(sprintf('%s%s', $marker, $item->getText()), $length)),
123+
$length,
124+
$style,
125+
$isSelected
139126
);
140-
}, explode("\n", $content));
141-
}, array_keys($this->items), $this->items);
142-
143-
$lines = max(array_map('count', $cells));
144-
145-
$rows = [];
146-
for ($i = 0; $i < $lines; $i++) {
147-
$row = "";
148-
if ($i > 0) {
149-
$row .= str_repeat(' ', 2);
150-
}
151-
foreach ($cells as $cell) {
152-
if (isset($cell[$i])) {
153-
$row .= $cell[$i];
154-
} else {
155-
$row .= str_repeat(' ', $length);
156-
}
157-
}
158-
if ($missingLength) {
159-
$row .= str_repeat(' ', $missingLength);
160-
}
161-
$rows[] = $row;
162-
}
163-
164-
return $rows;
127+
}, array_keys($this->items), $this->items),
128+
$missingLength,
129+
$length
130+
);
131+
}
132+
133+
private function buildRows(array $cells, int $missingLength, int $length) : array
134+
{
135+
return array_map(
136+
function ($i) use ($cells, $length, $missingLength) {
137+
return $this->buildRow($cells, $i, $length, $missingLength);
138+
},
139+
range(0, max(array_map('count', $cells)) - 1)
140+
);
141+
}
142+
143+
private function buildRow(array $cells, int $index, int $length, int $missingLength) : string
144+
{
145+
return sprintf(
146+
'%s%s',
147+
implode(
148+
'',
149+
array_map(
150+
function ($cell) use ($index, $length) {
151+
return $cell[$index] ?? str_repeat(' ', $length + $this->margin);
152+
},
153+
$cells
154+
)
155+
),
156+
str_repeat(' ', $missingLength)
157+
);
158+
}
159+
160+
private function buildCell(array $content, int $length, MenuStyle $style, bool $isSelected) : array
161+
{
162+
return array_map(function ($row) use ($length, $style, $isSelected) {
163+
$invertedColoursSetCode = $isSelected
164+
? $style->getInvertedColoursSetCode()
165+
: '';
166+
$invertedColoursUnsetCode = $isSelected
167+
? $style->getInvertedColoursUnsetCode()
168+
: '';
169+
170+
return sprintf(
171+
'%s%s%s%s%s',
172+
$invertedColoursSetCode,
173+
$row,
174+
str_repeat(' ', $length - mb_strlen($row)),
175+
$invertedColoursUnsetCode,
176+
str_repeat(' ', $this->margin)
177+
);
178+
}, $content);
165179
}
166180

167181
public function setSelectedItemIndex(int $index) : void
168182
{
183+
if (!isset($this->items[$index])) {
184+
throw new \InvalidArgumentException(sprintf('Index: "%s" does not exist', $index));
185+
}
186+
169187
$this->selectedItemIndex = $index;
170188
}
171189

@@ -232,6 +250,6 @@ public function hideItemExtra() : void
232250
*/
233251
public function getText() : string
234252
{
235-
throw new \BadMethodCallException(sprintf('Not supported on: %s', SplitItem::class));
253+
throw new \BadMethodCallException(sprintf('Not supported on: %s', __CLASS__));
236254
}
237255
}

0 commit comments

Comments
 (0)