diff --git a/src/CliMenu.php b/src/CliMenu.php index 569fd55b..f9173f1f 100644 --- a/src/CliMenu.php +++ b/src/CliMenu.php @@ -283,7 +283,17 @@ protected function moveSelectionVertically(string $direction) : void { $itemKeys = array_keys($this->items); + $increments = 0; + do { + $increments++; + + if ($increments > count($itemKeys)) { + //full cycle detected, there must be no selected items + //in the menu, so stop trying to select one. + return; + } + $direction === 'UP' ? $this->selectedItem-- : $this->selectedItem++; diff --git a/test/CliMenuTest.php b/test/CliMenuTest.php index 4656eea5..0436adfd 100644 --- a/test/CliMenuTest.php +++ b/test/CliMenuTest.php @@ -920,6 +920,20 @@ public function testGetSelectedItemThrowsExceptionIfNoSelectedItem() : void $menu->getSelectedItem(); } + public function testMenuCanOpenAndFunctionWithoutAnySelectableItems() : void + { + $this->terminal->expects($this->exactly(3)) + ->method('read') + ->willReturn("\033[B", "\033[B", 'Q'); + $menu = new CliMenu('PHP School FTW', [new StaticItem('One')], $this->terminal); + $menu->addCustomControlMapping('Q', function (CliMenu $menu) { + $menu->close(); + }); + $menu->open(); + + self::assertCount(1, $menu->getItems()); + } + private function getTestFile() : string { return sprintf('%s/res/%s.txt', __DIR__, $this->getName());