From 12607bfa105fd7a20118b0237e8bcbc3d493260f Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Sun, 15 Dec 2019 21:19:42 -0600 Subject: [PATCH 1/6] Initial toggleable item support --- examples/toggleable-item.php | 41 +++++++++ src/Builder/CliMenuBuilder.php | 26 ++++++ src/MenuItem/ToggleableItem.php | 143 ++++++++++++++++++++++++++++++++ src/MenuStyle.php | 80 ++++++++++++++---- 4 files changed, 274 insertions(+), 16 deletions(-) create mode 100644 examples/toggleable-item.php create mode 100644 src/MenuItem/ToggleableItem.php diff --git a/examples/toggleable-item.php b/examples/toggleable-item.php new file mode 100644 index 00000000..3f793a43 --- /dev/null +++ b/examples/toggleable-item.php @@ -0,0 +1,41 @@ +getSelectedItem(); + + $item->setToggled(!$item->getToggled()); + + $menu->redraw(); +}; + +$menu = (new CliMenuBuilder) + ->setTitle('Select a Language') + ->addSubMenu('Compiled', function (CliMenuBuilder $b) use($itemCallable) { + $b->setTitle('Compiled Languages') + ->addToggleableItem('Rust', $itemCallable) + ->addToggleableItem('C++', $itemCallable) + ->addToggleableItem('Go', $itemCallable) + ->addToggleableItem('Java', $itemCallable) + ->addToggleableItem('C', $itemCallable) + ; + }) + ->addSubMenu('Interpreted', function (CliMenuBuilder $b) use($itemCallable) { + $b->setTitle('Interpreted Languages') + ->setUntoggledMarker('[ ]') + ->setToggledMarker('[✔]') + ->addToggleableItem('PHP', $itemCallable) + ->addToggleableItem('Javascript', $itemCallable) + ->addToggleableItem('Ruby', $itemCallable) + ->addToggleableItem('Python', $itemCallable) + ; + }) + ->build(); + +$menu->open(); diff --git a/src/Builder/CliMenuBuilder.php b/src/Builder/CliMenuBuilder.php index af9668a6..0d4a64e1 100644 --- a/src/Builder/CliMenuBuilder.php +++ b/src/Builder/CliMenuBuilder.php @@ -10,6 +10,7 @@ use PhpSchool\CliMenu\MenuItem\MenuItemInterface; use PhpSchool\CliMenu\MenuItem\MenuMenuItem; use PhpSchool\CliMenu\MenuItem\SelectableItem; +use PhpSchool\CliMenu\MenuItem\ToggleableItem; use PhpSchool\CliMenu\CliMenu; use PhpSchool\CliMenu\MenuItem\SplitItem; use PhpSchool\CliMenu\MenuItem\StaticItem; @@ -130,6 +131,17 @@ public function addItems(array $items) : self return $this; } + public function addToggleableItem( + string $text, + callable $itemCallable, + bool $showItemExtra = false, + bool $disabled = false + ) : self { + $this->addMenuItem(new ToggleableItem($text, $itemCallable, $showItemExtra, $disabled)); + + return $this; + } + public function addStaticItem(string $text) : self { $this->addMenuItem(new StaticItem($text)); @@ -395,6 +407,20 @@ public function setSelectedMarker(string $marker) : self return $this; } + public function setUntoggledMarker(string $marker) : self + { + $this->style->setUntoggledMarker($marker); + + return $this; + } + + public function setToggledMarker(string $marker) : self + { + $this->style->setToggledMarker($marker); + + return $this; + } + public function setItemExtra(string $extra) : self { $this->style->setItemExtra($extra); diff --git a/src/MenuItem/ToggleableItem.php b/src/MenuItem/ToggleableItem.php new file mode 100644 index 00000000..12d0531e --- /dev/null +++ b/src/MenuItem/ToggleableItem.php @@ -0,0 +1,143 @@ +text = $text; + $this->selectAction = $selectAction; + $this->showItemExtra = $showItemExtra; + $this->disabled = $disabled; + } + + /** + * Execute the items callable if required + */ + public function getSelectAction() : ?callable + { + return $this->selectAction; + } + + /** + * Return the raw string of text + */ + public function getText() : string + { + return $this->text; + } + + /** + * Set the raw string of text + */ + public function setText(string $text) : void + { + $this->text = $text; + } + + /** + * The output text for the item + */ + public function getRows(MenuStyle $style, bool $toggled = false) : array + { + $marker = sprintf("%s", $style->getMarkerToggled($this->toggled)); + + $length = $style->getDisplaysExtra() + ? $style->getContentWidth() - (mb_strlen($style->getItemExtra()) + 2) + : $style->getContentWidth(); + + $rows = explode( + "\n", + StringUtil::wordwrap( + sprintf('%s %s', $marker, $this->text), + $length, + sprintf("\n%s", str_repeat(' ', mb_strlen($marker))) + ) + ); + + return array_map(function ($row, $key) use ($style, $length) { + $text = $this->disabled ? $style->getDisabledItemText($row) : $row; + + if ($key === 0) { + return $this->showItemExtra + ? sprintf('%s%s %s', $text, str_repeat(' ', $length - mb_strlen($row)), $style->getItemExtra()) + : $text; + } + + return $text; + }, $rows, array_keys($rows)); + } + + /** + * Can the item be selected + */ + public function canSelect() : bool + { + return !$this->disabled; + } + + public function showsItemExtra() : bool + { + return $this->showItemExtra; + } + + /** + * Enable showing item extra + */ + public function showItemExtra() : void + { + $this->showItemExtra = true; + } + + /** + * Disable showing item extra + */ + public function hideItemExtra() : void + { + $this->showItemExtra = false; + } + + public function setToggled(bool $toggled) + { + $this->toggled = $toggled; + } + + public function getToggled(): bool + { + return $this->toggled; + } +} diff --git a/src/MenuStyle.php b/src/MenuStyle.php index a740c40a..4f58dd85 100644 --- a/src/MenuStyle.php +++ b/src/MenuStyle.php @@ -69,6 +69,16 @@ class MenuStyle */ private $unselectedMarker; + /** + * @var string + */ + private $toggledMarker; + + /** + * @var string + */ + private $untoggledMarker; + /** * @var string */ @@ -150,23 +160,25 @@ class MenuStyle * @var array */ private static $defaultStyleValues = [ - 'fg' => 'white', - 'bg' => 'blue', - 'width' => 100, - 'paddingTopBottom' => 1, - 'paddingLeftRight' => 2, - 'margin' => 2, - 'selectedMarker' => '● ', - 'unselectedMarker' => '○ ', - 'itemExtra' => '✔', - 'displaysExtra' => false, - 'titleSeparator' => '=', - 'borderTopWidth' => 0, - 'borderRightWidth' => 0, + 'fg' => 'white', + 'bg' => 'blue', + 'width' => 100, + 'paddingTopBottom' => 1, + 'paddingLeftRight' => 2, + 'margin' => 2, + 'selectedMarker' => '● ', + 'unselectedMarker' => '○ ', + 'toggledMarker' => '[●] ', + 'untoggledMarker' => '[○] ', + 'itemExtra' => '✔', + 'displaysExtra' => false, + 'titleSeparator' => '=', + 'borderTopWidth' => 0, + 'borderRightWidth' => 0, 'borderBottomWidth' => 0, - 'borderLeftWidth' => 0, - 'borderColour' => 'white', - 'marginAuto' => false, + 'borderLeftWidth' => 0, + 'borderColour' => 'white', + 'marginAuto' => false, ]; /** @@ -229,6 +241,8 @@ public function __construct(Terminal $terminal = null) $this->setMargin(self::$defaultStyleValues['margin']); $this->setSelectedMarker(self::$defaultStyleValues['selectedMarker']); $this->setUnselectedMarker(self::$defaultStyleValues['unselectedMarker']); + $this->setToggledMarker(self::$defaultStyleValues['toggledMarker']); + $this->setUntoggledMarker(self::$defaultStyleValues['untoggledMarker']); $this->setItemExtra(self::$defaultStyleValues['itemExtra']); $this->setDisplaysExtra(self::$defaultStyleValues['displaysExtra']); $this->setTitleSeparator(self::$defaultStyleValues['titleSeparator']); @@ -250,6 +264,8 @@ public function hasChangedFromDefaults() : bool $this->margin, $this->selectedMarker, $this->unselectedMarker, + $this->toggledMarker, + $this->untoggledMarker, $this->itemExtra, $this->displaysExtra, $this->titleSeparator, @@ -557,6 +573,38 @@ public function getMarker(bool $selected) : string return $selected ? $this->selectedMarker : $this->unselectedMarker; } + public function getToggledMarker() : string + { + return $this->toggledMarker; + } + + public function setToggledMarker(string $marker) : self + { + $this->toggledMarker = $marker; + + return $this; + } + + public function getUntoggledMarker() : string + { + return $this->untoggledMarker; + } + + public function setUntoggledMarker(string $marker) : self + { + $this->untoggledMarker = $marker; + + return $this; + } + + /** + * Get the correct toggled marker for the item + */ + public function getMarkerToggled(bool $toggled) : string + { + return $toggled ? $this->toggledMarker : $this->untoggledMarker; + } + public function setItemExtra(string $itemExtra) : self { $this->itemExtra = $itemExtra; From 5bfa6cac836f7c53b015f42e092c9a5bf50862e0 Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Mon, 16 Dec 2019 10:49:42 -0600 Subject: [PATCH 2/6] PR change requests --- examples/checkable-item.php | 41 +++++++++++ examples/toggleable-item.php | 41 ----------- src/Builder/CliMenuBuilder.php | 14 ++-- .../{ToggleableItem.php => CheckableItem.php} | 41 ++++++++--- src/MenuStyle.php | 72 +++++++++---------- 5 files changed, 112 insertions(+), 97 deletions(-) create mode 100644 examples/checkable-item.php delete mode 100644 examples/toggleable-item.php rename src/MenuItem/{ToggleableItem.php => CheckableItem.php} (74%) diff --git a/examples/checkable-item.php b/examples/checkable-item.php new file mode 100644 index 00000000..8ef81534 --- /dev/null +++ b/examples/checkable-item.php @@ -0,0 +1,41 @@ +getSelectedItem(); + + $item->check(); + + $menu->redraw(); +}; + +$menu = (new CliMenuBuilder) + ->setTitle('Select a Language') + ->addSubMenu('Compiled', function (CliMenuBuilder $b) use($itemCallable) { + $b->setTitle('Compiled Languages') + ->addCheckableItem('Rust', $itemCallable) + ->addCheckableItem('C++', $itemCallable) + ->addCheckableItem('Go', $itemCallable) + ->addCheckableItem('Java', $itemCallable) + ->addCheckableItem('C', $itemCallable) + ; + }) + ->addSubMenu('Interpreted', function (CliMenuBuilder $b) use($itemCallable) { + $b->setTitle('Interpreted Languages') + ->setUncheckedMarker('[○] ') + ->setCheckedMarker('[●] ') + ->addCheckableItem('PHP', $itemCallable) + ->addCheckableItem('Javascript', $itemCallable) + ->addCheckableItem('Ruby', $itemCallable) + ->addCheckableItem('Python', $itemCallable) + ; + }) + ->build(); + +$menu->open(); diff --git a/examples/toggleable-item.php b/examples/toggleable-item.php deleted file mode 100644 index 3f793a43..00000000 --- a/examples/toggleable-item.php +++ /dev/null @@ -1,41 +0,0 @@ -getSelectedItem(); - - $item->setToggled(!$item->getToggled()); - - $menu->redraw(); -}; - -$menu = (new CliMenuBuilder) - ->setTitle('Select a Language') - ->addSubMenu('Compiled', function (CliMenuBuilder $b) use($itemCallable) { - $b->setTitle('Compiled Languages') - ->addToggleableItem('Rust', $itemCallable) - ->addToggleableItem('C++', $itemCallable) - ->addToggleableItem('Go', $itemCallable) - ->addToggleableItem('Java', $itemCallable) - ->addToggleableItem('C', $itemCallable) - ; - }) - ->addSubMenu('Interpreted', function (CliMenuBuilder $b) use($itemCallable) { - $b->setTitle('Interpreted Languages') - ->setUntoggledMarker('[ ]') - ->setToggledMarker('[✔]') - ->addToggleableItem('PHP', $itemCallable) - ->addToggleableItem('Javascript', $itemCallable) - ->addToggleableItem('Ruby', $itemCallable) - ->addToggleableItem('Python', $itemCallable) - ; - }) - ->build(); - -$menu->open(); diff --git a/src/Builder/CliMenuBuilder.php b/src/Builder/CliMenuBuilder.php index 0d4a64e1..7bd4188d 100644 --- a/src/Builder/CliMenuBuilder.php +++ b/src/Builder/CliMenuBuilder.php @@ -6,11 +6,11 @@ use PhpSchool\CliMenu\Action\GoBackAction; use PhpSchool\CliMenu\Exception\InvalidShortcutException; use PhpSchool\CliMenu\MenuItem\AsciiArtItem; +use PhpSchool\CliMenu\MenuItem\CheckableItem; use PhpSchool\CliMenu\MenuItem\LineBreakItem; use PhpSchool\CliMenu\MenuItem\MenuItemInterface; use PhpSchool\CliMenu\MenuItem\MenuMenuItem; use PhpSchool\CliMenu\MenuItem\SelectableItem; -use PhpSchool\CliMenu\MenuItem\ToggleableItem; use PhpSchool\CliMenu\CliMenu; use PhpSchool\CliMenu\MenuItem\SplitItem; use PhpSchool\CliMenu\MenuItem\StaticItem; @@ -131,13 +131,13 @@ public function addItems(array $items) : self return $this; } - public function addToggleableItem( + public function addCheckableItem( string $text, callable $itemCallable, bool $showItemExtra = false, bool $disabled = false ) : self { - $this->addMenuItem(new ToggleableItem($text, $itemCallable, $showItemExtra, $disabled)); + $this->addMenuItem(new CheckableItem($text, $itemCallable, $showItemExtra, $disabled)); return $this; } @@ -407,16 +407,16 @@ public function setSelectedMarker(string $marker) : self return $this; } - public function setUntoggledMarker(string $marker) : self + public function setUncheckedMarker(string $marker) : self { - $this->style->setUntoggledMarker($marker); + $this->style->setUncheckedMarker($marker); return $this; } - public function setToggledMarker(string $marker) : self + public function setCheckedMarker(string $marker) : self { - $this->style->setToggledMarker($marker); + $this->style->setCheckedMarker($marker); return $this; } diff --git a/src/MenuItem/ToggleableItem.php b/src/MenuItem/CheckableItem.php similarity index 74% rename from src/MenuItem/ToggleableItem.php rename to src/MenuItem/CheckableItem.php index 12d0531e..19841865 100644 --- a/src/MenuItem/ToggleableItem.php +++ b/src/MenuItem/CheckableItem.php @@ -6,7 +6,7 @@ use PhpSchool\CliMenu\MenuStyle; use PhpSchool\CliMenu\Util\StringUtil; -class ToggleableItem implements MenuItem\MenuItemInterface +class CheckableItem implements MenuItem\MenuItemInterface { /** * @var callable @@ -31,7 +31,7 @@ class ToggleableItem implements MenuItem\MenuItemInterface /** * @var bool */ - private $toggled = false; + private $checked = false; public function __construct( string $text, @@ -71,10 +71,14 @@ public function setText(string $text) : void /** * The output text for the item + * + * @param MenuStyle $style + * @param bool $selected Currently unused in this class + * @return array */ - public function getRows(MenuStyle $style, bool $toggled = false) : array + public function getRows(MenuStyle $style, bool $selected = false) : array { - $marker = sprintf("%s", $style->getMarkerToggled($this->toggled)); + $marker = sprintf("%s", $this->checked ? $style->getCheckedMarker() : $style->getUncheckedMarker()); $length = $style->getDisplaysExtra() ? $style->getContentWidth() - (mb_strlen($style->getItemExtra()) + 2) @@ -83,7 +87,7 @@ public function getRows(MenuStyle $style, bool $toggled = false) : array $rows = explode( "\n", StringUtil::wordwrap( - sprintf('%s %s', $marker, $this->text), + sprintf('%s%s', $marker, $this->text), $length, sprintf("\n%s", str_repeat(' ', mb_strlen($marker))) ) @@ -131,13 +135,32 @@ public function hideItemExtra() : void $this->showItemExtra = false; } - public function setToggled(bool $toggled) + /** + * Toggles checked state + */ + public function check() + { + $this->checked = !$this->checked; + } + + /** + * Sets checked state to true + */ + public function setChecked() + { + $this->checked = true; + } + + /** + * Sets checked state to false + */ + public function setUnchecked() { - $this->toggled = $toggled; + $this->checked = false; } - public function getToggled(): bool + public function getChecked(): bool { - return $this->toggled; + return $this->checked; } } diff --git a/src/MenuStyle.php b/src/MenuStyle.php index 4f58dd85..eececec9 100644 --- a/src/MenuStyle.php +++ b/src/MenuStyle.php @@ -72,12 +72,12 @@ class MenuStyle /** * @var string */ - private $toggledMarker; + private $checkedMarker; /** * @var string */ - private $untoggledMarker; + private $uncheckedMarker; /** * @var string @@ -160,25 +160,25 @@ class MenuStyle * @var array */ private static $defaultStyleValues = [ - 'fg' => 'white', - 'bg' => 'blue', - 'width' => 100, - 'paddingTopBottom' => 1, - 'paddingLeftRight' => 2, - 'margin' => 2, - 'selectedMarker' => '● ', - 'unselectedMarker' => '○ ', - 'toggledMarker' => '[●] ', - 'untoggledMarker' => '[○] ', - 'itemExtra' => '✔', - 'displaysExtra' => false, - 'titleSeparator' => '=', - 'borderTopWidth' => 0, - 'borderRightWidth' => 0, + 'fg' => 'white', + 'bg' => 'blue', + 'width' => 100, + 'paddingTopBottom' => 1, + 'paddingLeftRight' => 2, + 'margin' => 2, + 'selectedMarker' => '● ', + 'unselectedMarker' => '○ ', + 'checkedMarker' => '[✔] ', + 'uncheckedMarker' => '[ ] ', + 'itemExtra' => '✔', + 'displaysExtra' => false, + 'titleSeparator' => '=', + 'borderTopWidth' => 0, + 'borderRightWidth' => 0, 'borderBottomWidth' => 0, - 'borderLeftWidth' => 0, - 'borderColour' => 'white', - 'marginAuto' => false, + 'borderLeftWidth' => 0, + 'borderColour' => 'white', + 'marginAuto' => false, ]; /** @@ -241,8 +241,8 @@ public function __construct(Terminal $terminal = null) $this->setMargin(self::$defaultStyleValues['margin']); $this->setSelectedMarker(self::$defaultStyleValues['selectedMarker']); $this->setUnselectedMarker(self::$defaultStyleValues['unselectedMarker']); - $this->setToggledMarker(self::$defaultStyleValues['toggledMarker']); - $this->setUntoggledMarker(self::$defaultStyleValues['untoggledMarker']); + $this->setCheckedMarker(self::$defaultStyleValues['checkedMarker']); + $this->setUncheckedMarker(self::$defaultStyleValues['uncheckedMarker']); $this->setItemExtra(self::$defaultStyleValues['itemExtra']); $this->setDisplaysExtra(self::$defaultStyleValues['displaysExtra']); $this->setTitleSeparator(self::$defaultStyleValues['titleSeparator']); @@ -264,8 +264,8 @@ public function hasChangedFromDefaults() : bool $this->margin, $this->selectedMarker, $this->unselectedMarker, - $this->toggledMarker, - $this->untoggledMarker, + $this->checkedMarker, + $this->uncheckedMarker, $this->itemExtra, $this->displaysExtra, $this->titleSeparator, @@ -573,38 +573,30 @@ public function getMarker(bool $selected) : string return $selected ? $this->selectedMarker : $this->unselectedMarker; } - public function getToggledMarker() : string + public function getCheckedMarker() : string { - return $this->toggledMarker; + return $this->checkedMarker; } - public function setToggledMarker(string $marker) : self + public function setCheckedMarker(string $marker) : self { - $this->toggledMarker = $marker; + $this->checkedMarker = $marker; return $this; } - public function getUntoggledMarker() : string + public function getUncheckedMarker() : string { - return $this->untoggledMarker; + return $this->uncheckedMarker; } - public function setUntoggledMarker(string $marker) : self + public function setUncheckedMarker(string $marker) : self { - $this->untoggledMarker = $marker; + $this->uncheckedMarker = $marker; return $this; } - /** - * Get the correct toggled marker for the item - */ - public function getMarkerToggled(bool $toggled) : string - { - return $toggled ? $this->toggledMarker : $this->untoggledMarker; - } - public function setItemExtra(string $itemExtra) : self { $this->itemExtra = $itemExtra; From 8b567658fb849df056d043d3da9bebee5066ebf5 Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Mon, 16 Dec 2019 10:52:59 -0600 Subject: [PATCH 3/6] Spacing --- examples/checkable-item.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/checkable-item.php b/examples/checkable-item.php index 8ef81534..01501013 100644 --- a/examples/checkable-item.php +++ b/examples/checkable-item.php @@ -17,7 +17,7 @@ $menu = (new CliMenuBuilder) ->setTitle('Select a Language') - ->addSubMenu('Compiled', function (CliMenuBuilder $b) use($itemCallable) { + ->addSubMenu('Compiled', function (CliMenuBuilder $b) use ($itemCallable) { $b->setTitle('Compiled Languages') ->addCheckableItem('Rust', $itemCallable) ->addCheckableItem('C++', $itemCallable) @@ -26,7 +26,7 @@ ->addCheckableItem('C', $itemCallable) ; }) - ->addSubMenu('Interpreted', function (CliMenuBuilder $b) use($itemCallable) { + ->addSubMenu('Interpreted', function (CliMenuBuilder $b) use ($itemCallable) { $b->setTitle('Interpreted Languages') ->setUncheckedMarker('[○] ') ->setCheckedMarker('[●] ') From bc0bdf7d5f721306e879afbcd5d0970bffcc814d Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Mon, 16 Dec 2019 10:59:20 -0600 Subject: [PATCH 4/6] check -> toggle --- src/MenuItem/CheckableItem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MenuItem/CheckableItem.php b/src/MenuItem/CheckableItem.php index 19841865..93f021d7 100644 --- a/src/MenuItem/CheckableItem.php +++ b/src/MenuItem/CheckableItem.php @@ -138,7 +138,7 @@ public function hideItemExtra() : void /** * Toggles checked state */ - public function check() + public function toggle() { $this->checked = !$this->checked; } From 7088fe98cac69a50c26385b625f17578341e3712 Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Mon, 16 Dec 2019 11:44:16 -0600 Subject: [PATCH 5/6] Unit tests for CheckableItems --- test/Builder/CliMenuBuilderTest.php | 30 ++++++ test/MenuItem/CheckableItemTest.php | 160 ++++++++++++++++++++++++++++ test/MenuStyleTest.php | 4 + 3 files changed, 194 insertions(+) create mode 100644 test/MenuItem/CheckableItemTest.php diff --git a/test/Builder/CliMenuBuilderTest.php b/test/Builder/CliMenuBuilderTest.php index a57bfae2..70e72c68 100644 --- a/test/Builder/CliMenuBuilderTest.php +++ b/test/Builder/CliMenuBuilderTest.php @@ -5,6 +5,7 @@ use PhpSchool\CliMenu\CliMenu; use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\MenuItem\AsciiArtItem; +use PhpSchool\CliMenu\MenuItem\CheckableItem; use PhpSchool\CliMenu\MenuItem\LineBreakItem; use PhpSchool\CliMenu\MenuItem\MenuMenuItem; use PhpSchool\CliMenu\MenuItem\SelectableItem; @@ -64,6 +65,8 @@ public function testModifyStyles() : void $builder->setMargin(4); $builder->setUnselectedMarker('>'); $builder->setSelectedMarker('x'); + $builder->setUncheckedMarker('-'); + $builder->setCheckedMarker('+'); $builder->setItemExtra('*'); $builder->setTitleSeparator('-'); @@ -78,6 +81,8 @@ public function testModifyStyles() : void self::assertEquals(4, $style->getMargin()); self::assertEquals('>', $style->getUnselectedMarker()); self::assertEquals('x', $style->getSelectedMarker()); + self::assertEquals('-', $style->getUncheckedMarker()); + self::assertEquals('+', $style->getCheckedMarker()); self::assertEquals('*', $style->getItemExtra()); self::assertEquals('-', $style->getTitleSeparator()); } @@ -364,6 +369,31 @@ public function testAddMultipleItems() : void $this->checkMenuItems($menu, $expected); } + public function testAddCheckableItem() : void + { + $callable = function () { + }; + + $builder = new CliMenuBuilder; + $builder->disableDefaultItems(); + $builder->addCheckableItem('Item 1', $callable); + $builder->addCheckableItem('Item 2', $callable); + $menu = $builder->build(); + + $expected = [ + [ + 'class' => CheckableItem::class, + 'text' => 'Item 1', + ], + [ + 'class' => CheckableItem::class, + 'text' => 'Item 2', + ], + ]; + + $this->checkMenuItems($menu, $expected); + } + public function testAddStaticItem() : void { diff --git a/test/MenuItem/CheckableItemTest.php b/test/MenuItem/CheckableItemTest.php new file mode 100644 index 00000000..4b947fb1 --- /dev/null +++ b/test/MenuItem/CheckableItemTest.php @@ -0,0 +1,160 @@ +assertTrue($item->canSelect()); + } + + public function testGetSelectAction() : void + { + $callable = function () { + }; + $item = new CheckableItem('Item', $callable); + $this->assertSame($callable, $item->getSelectAction()); + } + + public function testShowsItemExtra() : void + { + $item = new CheckableItem('Item', function () { + }); + $this->assertFalse($item->showsItemExtra()); + + $item = new CheckableItem('Item', function () { + }, true); + $this->assertTrue($item->showsItemExtra()); + } + + public function testGetText() : void + { + $item = new CheckableItem('Item', function () { + }); + $this->assertEquals('Item', $item->getText()); + } + + public function testGetRows() : void + { + $terminal = $this->createMock(Terminal::class); + $terminal->expects($this->any())->method('getWidth')->willReturn(100); + + $menuStyle = new MenuStyle($terminal); + $menuStyle->setPaddingLeftRight(0); + $menuStyle->setWidth(8); + + $item = new CheckableItem('Item', function () { + }); + + $itemChecked = new CheckableItem('Item', function () { + }); + $itemChecked->toggle(); + $this->assertEquals(['[ ] Item'], $item->getRows($menuStyle)); + $this->assertEquals(['[ ] Item'], $item->getRows($menuStyle, false)); + $this->assertEquals(['[✔] Item'], $itemChecked->getRows($menuStyle, true)); + } + + public function testSetText() : void + { + $terminal = $this->createMock(Terminal::class); + $terminal->expects($this->any())->method('getWidth')->willReturn(100); + + $menuStyle = new MenuStyle($terminal); + $menuStyle->setPaddingLeftRight(0); + $menuStyle->setWidth(12); + + $item = new CheckableItem('Item', function () { + }); + $item->setText('New Text'); + + $itemChecked = new CheckableItem('Item', function () { + }); + $itemChecked->setText('New Text'); + $itemChecked->toggle(); + $this->assertEquals(['[ ] New Text'], $item->getRows($menuStyle)); + $this->assertEquals(['[ ] New Text'], $item->getRows($menuStyle, false)); + $this->assertEquals(['[✔] New Text'], $itemChecked->getRows($menuStyle, true)); + } + + public function testTogglesMarker() : void + { + $terminal = $this->createMock(Terminal::class); + $terminal->expects($this->any())->method('getWidth')->willReturn(100); + + $menuStyle = new MenuStyle($terminal); + $menuStyle->setPaddingLeftRight(0); + $menuStyle->setWidth(12); + + $item = new CheckableItem('Item', function () { + }); + + $itemChecked = new CheckableItem('Item', function () { + }); + $itemChecked->toggle(); + $this->assertEquals(['[ ] Item'], $item->getRows($menuStyle)); + $this->assertEquals(['[ ] Item'], $item->getRows($menuStyle, false)); + $this->assertEquals(['[✔] Item'], $itemChecked->getRows($menuStyle, true)); + + $itemChecked->toggle(); + + $this->assertEquals(['[ ] Item'], $itemChecked->getRows($menuStyle, true)); + } + + public function testGetRowsWithItemExtra() : void + { + $terminal = $this->createMock(Terminal::class); + $terminal->expects($this->any())->method('getWidth')->willReturn(100); + + $menuStyle = new MenuStyle($terminal); + $menuStyle->setPaddingLeftRight(0); + $menuStyle->setWidth(20); + $menuStyle->setItemExtra('[EXTRA]'); + $menuStyle->setDisplaysExtra(true); + + $item = new CheckableItem('Item', function () { + }, true); + $this->assertEquals(['[ ] Item [EXTRA]'], $item->getRows($menuStyle)); + } + + public function testGetRowsWithMultipleLinesWithItemExtra() : void + { + $terminal = $this->createMock(Terminal::class); + $terminal->expects($this->any())->method('getWidth')->willReturn(100); + + $menuStyle = new MenuStyle($terminal); + $menuStyle->setPaddingLeftRight(0); + $menuStyle->setWidth(20); + $menuStyle->setItemExtra('[EXTRA]'); + $menuStyle->setDisplaysExtra(true); + + $item = new CheckableItem('LONG ITEM LINE', function () { + }, true); + $this->assertEquals( + [ + "[ ] LONG [EXTRA]", + " ITEM LINE", + ], + $item->getRows($menuStyle) + ); + } + + public function testHideAndShowItemExtra() : void + { + $item = new CheckableItem('Item', function () { + }); + + $this->assertFalse($item->showsItemExtra()); + $item->showItemExtra(); + $this->assertTrue($item->showsItemExtra()); + $item->hideItemExtra(); + $this->assertFalse($item->showsItemExtra()); + } +} diff --git a/test/MenuStyleTest.php b/test/MenuStyleTest.php index 1c954cc3..6f40fb35 100644 --- a/test/MenuStyleTest.php +++ b/test/MenuStyleTest.php @@ -100,6 +100,8 @@ public function testGetterAndSetters() : void $style->setFg('yellow'); $style->setUnselectedMarker('-'); $style->setSelectedMarker('>'); + $style->setUncheckedMarker('/'); + $style->setCheckedMarker('+'); $style->setItemExtra('EXTRA!'); $style->setDisplaysExtra(true); $style->setTitleSeparator('+'); @@ -117,6 +119,8 @@ public function testGetterAndSetters() : void self::assertSame('yellow', $style->getFg()); self::assertSame('-', $style->getUnselectedMarker()); self::assertSame('>', $style->getSelectedMarker()); + self::assertEquals('/', $style->getUncheckedMarker()); + self::assertEquals('+', $style->getCheckedMarker()); self::assertSame('EXTRA!', $style->getItemExtra()); self::assertTrue($style->getDisplaysExtra()); self::assertSame('+', $style->getTitleSeparator()); From 86416ab191bd674a41f00f5c2c4b96a6157ecf82 Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Mon, 16 Dec 2019 12:21:58 -0600 Subject: [PATCH 6/6] check() -> toggle() --- examples/checkable-item.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/checkable-item.php b/examples/checkable-item.php index 01501013..13fdde04 100644 --- a/examples/checkable-item.php +++ b/examples/checkable-item.php @@ -10,7 +10,7 @@ /** @var CheckableItem $item */ $item = $menu->getSelectedItem(); - $item->check(); + $item->toggle(); $menu->redraw(); };