diff --git a/composer.json b/composer.json index cf9d9dd..dec0e1d 100644 --- a/composer.json +++ b/composer.json @@ -20,21 +20,21 @@ "prefer-stable": true, "require": { "php": "^7.4|^8.0", - "npm-asset/bulma": "^0.9.1", + "npm-asset/bulma": "^0.9.3", "npm-asset/bulma-helpers": "^0.3.12", "npm-asset/vizuaalog--bulmajs": "^0.11.0", "oomphinc/composer-installers-extender": "^2.0.0", - "yiisoft/arrays": "@dev", + "yiisoft/arrays": "^1.0", "yiisoft/assets": "^1.0", - "yiisoft/html": "^1.0", + "yiisoft/html": "^1.2", "yiisoft/widget": "@dev" }, "require-dev": { "phpunit/phpunit": "^9.5", - "roave/infection-static-analysis-plugin": "^1.", + "roave/infection-static-analysis-plugin": "^1.8", "spatie/phpunit-watcher": "^1.23", - "vimeo/psalm": "^4.3", - "yiisoft/di": "^3.0@dev" + "vimeo/psalm": "^4.8", + "yiisoft/test-support": "^1.3" }, "autoload": { "psr-4": { diff --git a/psalm.xml b/psalm.xml index 25dc41e..baa9178 100644 --- a/psalm.xml +++ b/psalm.xml @@ -7,9 +7,5 @@ > - - - - diff --git a/src/Asset/BulmaAsset.php b/src/Asset/BulmaAsset.php index 8c7af65..4d89b96 100644 --- a/src/Asset/BulmaAsset.php +++ b/src/Asset/BulmaAsset.php @@ -10,14 +10,12 @@ final class BulmaAsset extends AssetBundle { public ?string $basePath = '@assets'; public ?string $baseUrl = '@assetsUrl'; - public ?string $sourcePath = '@npm/bulma/'; + public ?string $sourcePath = '@npm/bulma'; - /** @psalm-suppress NonInvariantDocblockPropertyType */ public array $css = [ 'css/bulma.css', ]; - /** @psalm-suppress NonInvariantDocblockPropertyType */ public array $publishOptions = [ 'only' => [ 'css/bulma.css', diff --git a/src/Asset/BulmaHelpersAsset.php b/src/Asset/BulmaHelpersAsset.php index aa94d05..5d9d11d 100644 --- a/src/Asset/BulmaHelpersAsset.php +++ b/src/Asset/BulmaHelpersAsset.php @@ -12,12 +12,10 @@ final class BulmaHelpersAsset extends AssetBundle public ?string $baseUrl = '@assetsUrl'; public ?string $sourcePath = '@npm/bulma-helpers/css'; - /** @psalm-suppress NonInvariantDocblockPropertyType */ public array $css = [ 'bulma-helpers.css', ]; - /** @psalm-suppress NonInvariantDocblockPropertyType */ public array $publishOptions = [ 'only' => [ 'bulma-helpers.css', diff --git a/src/Asset/BulmaJsAsset.php b/src/Asset/BulmaJsAsset.php index cfe3b14..4fe166c 100644 --- a/src/Asset/BulmaJsAsset.php +++ b/src/Asset/BulmaJsAsset.php @@ -12,12 +12,10 @@ final class BulmaJsAsset extends AssetBundle public ?string $baseUrl = '@assetsUrl'; public ?string $sourcePath = '@npm/vizuaalog--bulmajs'; - /** @psalm-suppress NonInvariantDocblockPropertyType */ public array $js = [ 'dist/bulma.js', ]; - /** @psalm-suppress NonInvariantDocblockPropertyType */ public array $publishOptions = [ 'only' => [ 'dist/bulma.js', diff --git a/src/Asset/FilePluginAsset.php b/src/Asset/FilePluginAsset.php index 9f4dff5..129273f 100644 --- a/src/Asset/FilePluginAsset.php +++ b/src/Asset/FilePluginAsset.php @@ -12,12 +12,10 @@ final class FilePluginAsset extends AssetBundle public ?string $baseUrl = '@assetsUrl'; public ?string $sourcePath = '@npm/vizuaalog--bulmajs'; - /** @psalm-suppress NonInvariantDocblockPropertyType */ public array $js = [ 'dist/file.js', ]; - /** @psalm-suppress NonInvariantDocblockPropertyType */ public array $publishOptions = [ 'only' => [ 'dist/file.js', diff --git a/src/Breadcrumbs.php b/src/Breadcrumbs.php index d58270c..27ee116 100644 --- a/src/Breadcrumbs.php +++ b/src/Breadcrumbs.php @@ -26,7 +26,7 @@ * * @link https://bulma.io/documentation/components/breadcrumb/ */ -class Breadcrumbs extends Widget +final class Breadcrumbs extends Widget { private bool $encodeLabels = true; private bool $encodeLinks = false; diff --git a/src/Menu.php b/src/Menu.php index e24d169..b904c67 100644 --- a/src/Menu.php +++ b/src/Menu.php @@ -86,7 +86,7 @@ public function activateParents(): self /** * The CSS class to be appended to the active menu item. * - * @var string + * @param string $value * * @return self */ @@ -141,7 +141,7 @@ public function withoutEncodeLabels(): self * The CSS class that will be assigned to the first item in the main menu or each submenu. Defaults to null, * meaning no such CSS class will be assigned. * - * @var string + * @param string $value * * @return self */ @@ -156,8 +156,6 @@ public function firstItemCssClass(string $value): self * Whether to show empty menu items. An empty menu item is one whose `url` option is not set and which has no * visible child menu items. * - * @var bool - * * @return self */ public function showEmptyItems(): self diff --git a/src/ModalCard.php b/src/ModalCard.php index 740622f..ef48f66 100644 --- a/src/ModalCard.php +++ b/src/ModalCard.php @@ -209,8 +209,6 @@ public function toggleButtonColor(string $value): self /** * Disable toggle button. * - * @param bool $value - * * @return self */ public function withoutToggleButton(): self @@ -261,8 +259,6 @@ public function closeButtonOptions(array $value): self /** * Disable close button. * - * @param bool $value - * * @return self */ public function withoutCloseButton(): self diff --git a/src/Panel.php b/src/Panel.php index 5a52376..490ee9c 100644 --- a/src/Panel.php +++ b/src/Panel.php @@ -114,7 +114,7 @@ public function headingOptions(array $value): self /** * Set progress bar color. * - * @var string $value Color class. + * @param string $value Color class. * * @return self */ diff --git a/src/ProgressBar.php b/src/ProgressBar.php index 2da255c..cf777c3 100644 --- a/src/ProgressBar.php +++ b/src/ProgressBar.php @@ -76,7 +76,7 @@ public function options(array $value): self /** * Set the value of the progress. * - * @var float $value The value of the progress. Set `0` to display loading animation. + * @param float $value The value of the progress. Set `0` to display loading animation. * * @return self */ @@ -91,7 +91,7 @@ public function value(float $value): self /** * Set maximum progress value. * - * @var int $value Maximum progress value. Set `0` for no maximum. + * @param int $value Maximum progress value. Set `0` for no maximum. * * @return self */ @@ -126,7 +126,7 @@ public function size(string $value): self /** * Set progress bar color. * - * @var string $value Color class. + * @param string $value Color class. * * @return self */ @@ -151,7 +151,7 @@ private function buildOptions(): void $this->options = $this->addOptions($this->options, 'progress'); - if ($this->maxValue !== 0) { + if ($this->maxValue > 0) { $this->options['max'] = $this->maxValue; } diff --git a/src/Widget.php b/src/Widget.php index de42952..65a39df 100644 --- a/src/Widget.php +++ b/src/Widget.php @@ -83,6 +83,7 @@ protected function addOptions(array $options, string $defaultClass): array $class = ''; if (isset($options['class'])) { + /** @var string|string[] $class */ $class = $options['class']; unset($options['class']); @@ -91,7 +92,6 @@ protected function addOptions(array $options, string $defaultClass): array } } - /** @psalm-var string $class */ if (strpos($class, $defaultClass) === false) { Html::addCssClass($options, $defaultClass); } diff --git a/tests/BreadcrumbsTest.php b/tests/BreadcrumbsTest.php index 5b74347..f9a3e8f 100644 --- a/tests/BreadcrumbsTest.php +++ b/tests/BreadcrumbsTest.php @@ -284,4 +284,19 @@ public function testBreadcrumbsWithoutHomeItem(): void HTML; $this->assertEqualsWithoutLE($expected, $html); } + + public function testImmutability(): void + { + $widget = Breadcrumbs::widget(); + + $this->assertNotSame($widget, $widget->homeItem([])); + $this->assertNotSame($widget, $widget->withoutHomeItem()); + $this->assertNotSame($widget, $widget->itemTemplate('')); + $this->assertNotSame($widget, $widget->activeItemTemplate('')); + $this->assertNotSame($widget, $widget->items([])); + $this->assertNotSame($widget, $widget->options([])); + $this->assertNotSame($widget, $widget->itemsOptions([])); + $this->assertNotSame($widget, $widget->id(Breadcrumbs::class)); + $this->assertNotSame($widget, $widget->autoIdPrefix(Breadcrumbs::class)); + } } diff --git a/tests/DropdownTest.php b/tests/DropdownTest.php index 2c70391..225f740 100644 --- a/tests/DropdownTest.php +++ b/tests/DropdownTest.php @@ -259,4 +259,24 @@ public function testEncodeLabels(): void HTML; $this->assertEqualsWithoutLE($expected, $html); } + + public function testImmutability(): void + { + $widget = Dropdown::widget(); + + $this->assertNotSame($widget, $widget->buttonLabel('')); + $this->assertNotSame($widget, $widget->buttonLabelOptions([])); + $this->assertNotSame($widget, $widget->dividerClass('')); + $this->assertNotSame($widget, $widget->itemClass('')); + $this->assertNotSame($widget, $widget->itemsClass('')); + $this->assertNotSame($widget, $widget->withoutEncodeLabels()); + $this->assertNotSame($widget, $widget->withoutEncloseByContainer()); + $this->assertNotSame($widget, $widget->items([])); + $this->assertNotSame($widget, $widget->options([])); + $this->assertNotSame($widget, $widget->buttonOptions([])); + $this->assertNotSame($widget, $widget->itemsOptions([])); + $this->assertNotSame($widget, $widget->triggerOptions([])); + $this->assertNotSame($widget, $widget->id(Dropdown::class)); + $this->assertNotSame($widget, $widget->autoIdPrefix(Dropdown::class)); + } } diff --git a/tests/MenuTest.php b/tests/MenuTest.php index 9542118..a198229 100644 --- a/tests/MenuTest.php +++ b/tests/MenuTest.php @@ -873,4 +873,27 @@ public function testMenuSubMenuTemplate(): void HTML; $this->assertEqualsWithoutLE($expected, $html); } + + public function testImmutability(): void + { + $widget = Menu::widget(); + + $this->assertNotSame($widget, $widget->withoutActivateItems()); + $this->assertNotSame($widget, $widget->activateParents()); + $this->assertNotSame($widget, $widget->activeCssClass('')); + $this->assertNotSame($widget, $widget->brand('')); + $this->assertNotSame($widget, $widget->currentPath('')); + $this->assertNotSame($widget, $widget->withoutEncodeLabels()); + $this->assertNotSame($widget, $widget->firstItemCssClass('')); + $this->assertNotSame($widget, $widget->showEmptyItems()); + $this->assertNotSame($widget, $widget->items([])); + $this->assertNotSame($widget, $widget->itemOptions([])); + $this->assertNotSame($widget, $widget->labelTemplate('')); + $this->assertNotSame($widget, $widget->lastItemCssClass('')); + $this->assertNotSame($widget, $widget->linkTemplate('')); + $this->assertNotSame($widget, $widget->options([])); + $this->assertNotSame($widget, $widget->subMenuTemplate('')); + $this->assertNotSame($widget, $widget->id(Menu::class)); + $this->assertNotSame($widget, $widget->autoIdPrefix(Menu::class)); + } } diff --git a/tests/MessageTest.php b/tests/MessageTest.php index 450a837..4ef606d 100644 --- a/tests/MessageTest.php +++ b/tests/MessageTest.php @@ -253,4 +253,22 @@ public function testMessageWithoutHeader(): void HTML; $this->assertEqualsWithoutLE($expected, $html); } + + public function testImmutability(): void + { + $widget = Message::widget(); + + $this->assertNotSame($widget, $widget->body('')); + $this->assertNotSame($widget, $widget->headerColor('')); + $this->assertNotSame($widget, $widget->headerMessage('')); + $this->assertNotSame($widget, $widget->options([])); + $this->assertNotSame($widget, $widget->bodyOptions([])); + $this->assertNotSame($widget, $widget->closeButtonOptions([])); + $this->assertNotSame($widget, $widget->headerOptions([])); + $this->assertNotSame($widget, $widget->size('')); + $this->assertNotSame($widget, $widget->closeButton()); + $this->assertNotSame($widget, $widget->withoutHeader()); + $this->assertNotSame($widget, $widget->id(Message::class)); + $this->assertNotSame($widget, $widget->autoIdPrefix(Message::class)); + } } diff --git a/tests/ModalCardTest.php b/tests/ModalCardTest.php index 7a691fe..d010ad1 100644 --- a/tests/ModalCardTest.php +++ b/tests/ModalCardTest.php @@ -436,4 +436,28 @@ public function testModalCardOptions(): void HTML; $this->assertEqualsWithoutLE($expected, $html); } + + public function testImmutability(): void + { + $widget = ModalCard::widget(); + + $this->assertNotSame($widget, $widget->options([])); + $this->assertNotSame($widget, $widget->contentOptions([])); + $this->assertNotSame($widget, $widget->toggleButtonLabel('')); + $this->assertNotSame($widget, $widget->toggleButtonOptions([])); + $this->assertNotSame($widget, $widget->toggleButtonSize('is-small')); + $this->assertNotSame($widget, $widget->toggleButtonColor('is-primary')); + $this->assertNotSame($widget, $widget->withoutToggleButton()); + $this->assertNotSame($widget, $widget->closeButtonSize('is-small')); + $this->assertNotSame($widget, $widget->closeButtonOptions([])); + $this->assertNotSame($widget, $widget->withoutCloseButton()); + $this->assertNotSame($widget, $widget->headerOptions([])); + $this->assertNotSame($widget, $widget->bodyOptions([])); + $this->assertNotSame($widget, $widget->footerOptions([])); + $this->assertNotSame($widget, $widget->footer('')); + $this->assertNotSame($widget, $widget->titleOptions([])); + $this->assertNotSame($widget, $widget->title('')); + $this->assertNotSame($widget, $widget->id(ModalCard::class)); + $this->assertNotSame($widget, $widget->autoIdPrefix(ModalCard::class)); + } } diff --git a/tests/ModalTest.php b/tests/ModalTest.php index 2ec93ac..fff59cd 100644 --- a/tests/ModalTest.php +++ b/tests/ModalTest.php @@ -230,4 +230,22 @@ public function testToggleButtonOptions(): void HTML; $this->assertEqualsWithoutLE($expected, $html); } + + public function testImmutability(): void + { + $widget = Modal::widget(); + + $this->assertNotSame($widget, $widget->options([])); + $this->assertNotSame($widget, $widget->toggleButtonLabel('')); + $this->assertNotSame($widget, $widget->toggleButtonOptions([])); + $this->assertNotSame($widget, $widget->toggleButtonSize('is-small')); + $this->assertNotSame($widget, $widget->toggleButtonColor('is-primary')); + $this->assertNotSame($widget, $widget->withoutToggleButton()); + $this->assertNotSame($widget, $widget->closeButtonSize('is-small')); + $this->assertNotSame($widget, $widget->closeButtonOptions([])); + $this->assertNotSame($widget, $widget->withoutCloseButton()); + $this->assertNotSame($widget, $widget->contentOptions([])); + $this->assertNotSame($widget, $widget->id(Modal::class)); + $this->assertNotSame($widget, $widget->autoIdPrefix(Modal::class)); + } } diff --git a/tests/NavBarTest.php b/tests/NavBarTest.php index ce1ec96..eccbc29 100644 --- a/tests/NavBarTest.php +++ b/tests/NavBarTest.php @@ -418,4 +418,24 @@ public function testNavBarItemsOptionsClassArray(): void HTML; $this->assertEqualsWithoutLE($expected, $html); } + + public function testImmutability(): void + { + $widget = NavBar::widget(); + + $this->assertNotSame($widget, $widget->brand('')); + $this->assertNotSame($widget, $widget->brandLabel('')); + $this->assertNotSame($widget, $widget->brandImage('')); + $this->assertNotSame($widget, $widget->brandUrl('')); + $this->assertNotSame($widget, $widget->toggleIcon('')); + $this->assertNotSame($widget, $widget->options([])); + $this->assertNotSame($widget, $widget->brandOptions([])); + $this->assertNotSame($widget, $widget->brandLabelOptions([])); + $this->assertNotSame($widget, $widget->brandImageOptions([])); + $this->assertNotSame($widget, $widget->itemsOptions([])); + $this->assertNotSame($widget, $widget->menuOptions([])); + $this->assertNotSame($widget, $widget->toggleOptions([])); + $this->assertNotSame($widget, $widget->id(NavBar::class)); + $this->assertNotSame($widget, $widget->autoIdPrefix(NavBar::class)); + } } diff --git a/tests/NavTest.php b/tests/NavTest.php index 6ab9987..72d62d4 100644 --- a/tests/NavTest.php +++ b/tests/NavTest.php @@ -516,4 +516,17 @@ public function testNavIcon(): void HTML; $this->assertEqualsWithoutLE($expected, $html); } + + public function testImmutability(): void + { + $widget = Nav::widget(); + + $this->assertNotSame($widget, $widget->withoutActivateItems()); + $this->assertNotSame($widget, $widget->activateParents()); + $this->assertNotSame($widget, $widget->currentPath('')); + $this->assertNotSame($widget, $widget->withoutEncodeLabels()); + $this->assertNotSame($widget, $widget->items([])); + $this->assertNotSame($widget, $widget->id(Nav::class)); + $this->assertNotSame($widget, $widget->autoIdPrefix(Nav::class)); + } } diff --git a/tests/PanelTest.php b/tests/PanelTest.php index 97157e3..60a0446 100644 --- a/tests/PanelTest.php +++ b/tests/PanelTest.php @@ -398,4 +398,19 @@ public function testItemMissigLabel(): void $this->expectException(InvalidArgumentException::class); Panel::widget()->tabs([['label' => 'All', 'items' => [['icon' => 'fas fa-book']]]])->render(); } + + public function testImmutability(): void + { + $widget = Panel::widget(); + + $this->assertNotSame($widget, $widget->template('')); + $this->assertNotSame($widget, $widget->options([])); + $this->assertNotSame($widget, $widget->heading('')); + $this->assertNotSame($widget, $widget->headingOptions([])); + $this->assertNotSame($widget, $widget->color('is-primary')); + $this->assertNotSame($widget, $widget->tabs([])); + $this->assertNotSame($widget, $widget->tabsOptions([])); + $this->assertNotSame($widget, $widget->id(Panel::class)); + $this->assertNotSame($widget, $widget->autoIdPrefix(Panel::class)); + } } diff --git a/tests/ProgressBarTest.php b/tests/ProgressBarTest.php index fe009c7..2df39f2 100644 --- a/tests/ProgressBarTest.php +++ b/tests/ProgressBarTest.php @@ -78,6 +78,17 @@ public function testProgressBarPercent(): void $this->assertEqualsWithoutLE($expected, $html); } + public function testProgressBarWithZeroValues(): void + { + ProgressBar::counter(0); + + $html = ProgressBar::widget()->value(0)->maxValue(0)->render(); + $expected = <<<'HTML' + + HTML; + $this->assertEqualsWithoutLE($expected, $html); + } + public function testExceptionSize(): void { $this->expectException(InvalidArgumentException::class); @@ -89,4 +100,17 @@ public function testExceptionColor(): void $this->expectException(InvalidArgumentException::class); ProgressBar::widget()->color('is-non-existent')->render(); } + + public function testImmutability(): void + { + $widget = ProgressBar::widget(); + + $this->assertNotSame($widget, $widget->options([])); + $this->assertNotSame($widget, $widget->value(1.0)); + $this->assertNotSame($widget, $widget->maxValue(100)); + $this->assertNotSame($widget, $widget->size('is-small')); + $this->assertNotSame($widget, $widget->color('is-primary')); + $this->assertNotSame($widget, $widget->id(ProgressBar::class)); + $this->assertNotSame($widget, $widget->autoIdPrefix(ProgressBar::class)); + } } diff --git a/tests/TabsTest.php b/tests/TabsTest.php index 5612bd2..a93b297 100644 --- a/tests/TabsTest.php +++ b/tests/TabsTest.php @@ -331,4 +331,21 @@ public function testTabsContentOptions(): void HTML; $this->assertEqualsWithoutLE($expected, $html); } + + public function testImmutability(): void + { + $widget = Tabs::widget(); + + $this->assertNotSame($widget, $widget->options([])); + $this->assertNotSame($widget, $widget->items([])); + $this->assertNotSame($widget, $widget->withoutActivateItems()); + $this->assertNotSame($widget, $widget->withoutEncodeLabels()); + $this->assertNotSame($widget, $widget->currentPath('')); + $this->assertNotSame($widget, $widget->size('is-small')); + $this->assertNotSame($widget, $widget->alignment('is-centered')); + $this->assertNotSame($widget, $widget->style('is-boxed')); + $this->assertNotSame($widget, $widget->tabsContentOptions([])); + $this->assertNotSame($widget, $widget->id(Tabs::class)); + $this->assertNotSame($widget, $widget->autoIdPrefix(Tabs::class)); + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 6070acd..d12c414 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -6,7 +6,7 @@ use PHPUnit\Framework\TestCase as BaseTestCase; use Psr\Container\ContainerInterface; -use Yiisoft\Di\Container; +use Yiisoft\Test\Support\Container\SimpleContainer; use Yiisoft\Widget\WidgetFactory; abstract class TestCase extends BaseTestCase @@ -17,7 +17,7 @@ protected function setUp(): void { parent::setUp(); - $this->container = new Container(); + $this->container = new SimpleContainer(); WidgetFactory::initialize($this->container, []); }