diff --git a/src/Forms/Container.php b/src/Forms/Container.php index 92b5bbcb..51e3e1f4 100644 --- a/src/Forms/Container.php +++ b/src/Forms/Container.php @@ -319,6 +319,7 @@ public function getForm(bool $throw = true): ?Form /** * Adds single-line text input control to the form. + * @return Controls\TextInput */ public function addText( string $name, @@ -334,6 +335,7 @@ public function addText( /** * Adds single-line text input control used for sensitive input such as passwords. + * @return Controls\TextInput */ public function addPassword( string $name, @@ -350,6 +352,7 @@ public function addPassword( /** * Adds multi-line text input control to the form. + * @return Controls\TextInput */ public function addTextArea( string $name, @@ -365,6 +368,7 @@ public function addTextArea( /** * Adds input for email. + * @return Controls\TextInput */ public function addEmail(string $name, string|Stringable|null $label = null): Controls\TextInput { @@ -375,6 +379,7 @@ public function addEmail(string $name, string|Stringable|null $label = null): Co /** * Adds input for integer. + * @return Controls\TextInput */ public function addInteger(string $name, string|Stringable|null $label = null): Controls\TextInput { @@ -386,6 +391,7 @@ public function addInteger(string $name, string|Stringable|null $label = null): /** * Adds input for float. + * @return Controls\TextInput */ public function addFloat(string $name, string|Stringable|null $label = null): Controls\TextInput { @@ -434,6 +440,7 @@ public function addDateTime( /** * Adds control that allows the user to upload files. + * @return Controls\UploadControl */ public function addUpload(string $name, string|Stringable|null $label = null): Controls\UploadControl { @@ -443,6 +450,7 @@ public function addUpload(string $name, string|Stringable|null $label = null): C /** * Adds control that allows the user to upload multiple files. + * @return Controls\UploadControl */ public function addMultiUpload(string $name, string|Stringable|null $label = null): Controls\UploadControl { diff --git a/src/Forms/Control.php b/src/Forms/Control.php index 9eff4bf7..8a01a8f8 100644 --- a/src/Forms/Control.php +++ b/src/Forms/Control.php @@ -12,19 +12,20 @@ /** * Defines method that must be implemented to allow a component to act like a form control. + * @template T */ interface Control { /** * Sets control's value. - * @param mixed $value + * @param T|null $value * @return static */ function setValue(mixed $value); /** * Returns control's value. - * @return mixed + * @return T|null */ function getValue(); diff --git a/src/Forms/Controls/BaseControl.php b/src/Forms/Controls/BaseControl.php index 6b52ed24..a7039afd 100644 --- a/src/Forms/Controls/BaseControl.php +++ b/src/Forms/Controls/BaseControl.php @@ -36,6 +36,9 @@ * @property-read array $errors * @property-read array $options * @property-read string $error + * + * @template T + * @implements Control */ abstract class BaseControl extends Nette\ComponentModel\Component implements Control { @@ -145,7 +148,6 @@ public function setValue(mixed $value) /** * Returns control's value. - * @return mixed */ public function getValue() { diff --git a/src/Forms/Controls/Button.php b/src/Forms/Controls/Button.php index 021bbcc7..ccb59384 100644 --- a/src/Forms/Controls/Button.php +++ b/src/Forms/Controls/Button.php @@ -15,6 +15,7 @@ /** * Push button control with no default behavior. + * @extends BaseControl */ class Button extends BaseControl { diff --git a/src/Forms/Controls/Checkbox.php b/src/Forms/Controls/Checkbox.php index 61a58a67..c1b06a34 100644 --- a/src/Forms/Controls/Checkbox.php +++ b/src/Forms/Controls/Checkbox.php @@ -16,6 +16,7 @@ /** * Check box control. Allows the user to select a true or false condition. + * @extends BaseControl */ class Checkbox extends BaseControl { diff --git a/src/Forms/Controls/ChoiceControl.php b/src/Forms/Controls/ChoiceControl.php index ec817645..5ccc33bc 100644 --- a/src/Forms/Controls/ChoiceControl.php +++ b/src/Forms/Controls/ChoiceControl.php @@ -17,6 +17,8 @@ * * @property array $items * @property-read mixed $selectedItem + * + * @extends BaseControl */ abstract class ChoiceControl extends BaseControl { @@ -71,7 +73,6 @@ public function setValue($value): static /** * Returns selected key. - * @return string|int|null */ public function getValue(): mixed { diff --git a/src/Forms/Controls/ColorPicker.php b/src/Forms/Controls/ColorPicker.php index 0b82a9bd..cb849027 100644 --- a/src/Forms/Controls/ColorPicker.php +++ b/src/Forms/Controls/ColorPicker.php @@ -14,6 +14,7 @@ /** * Color picker. + * @extends BaseControl */ class ColorPicker extends BaseControl { diff --git a/src/Forms/Controls/CsrfProtection.php b/src/Forms/Controls/CsrfProtection.php index f50b843e..22006270 100644 --- a/src/Forms/Controls/CsrfProtection.php +++ b/src/Forms/Controls/CsrfProtection.php @@ -16,6 +16,7 @@ /** * CSRF protection field. + * @extends BaseControl */ class CsrfProtection extends HiddenField { diff --git a/src/Forms/Controls/DateTimeControl.php b/src/Forms/Controls/DateTimeControl.php index c1eff5aa..a19d9212 100644 --- a/src/Forms/Controls/DateTimeControl.php +++ b/src/Forms/Controls/DateTimeControl.php @@ -16,6 +16,7 @@ /** * Selects date or time or date & time. + * @extends BaseControl<\DateTimeInterface|string|int|null> */ class DateTimeControl extends BaseControl { diff --git a/src/Forms/Controls/HiddenField.php b/src/Forms/Controls/HiddenField.php index 9db1c693..7397b066 100644 --- a/src/Forms/Controls/HiddenField.php +++ b/src/Forms/Controls/HiddenField.php @@ -16,6 +16,7 @@ /** * Hidden form control used to store a non-displayed value. + * @extends BaseControl */ class HiddenField extends BaseControl { diff --git a/src/Forms/Controls/ImageButton.php b/src/Forms/Controls/ImageButton.php index 035fcbe0..9711a186 100644 --- a/src/Forms/Controls/ImageButton.php +++ b/src/Forms/Controls/ImageButton.php @@ -12,6 +12,7 @@ /** * Submittable image button form control. + * @method array|null getValue() */ class ImageButton extends SubmitButton { diff --git a/src/Forms/Controls/MultiChoiceControl.php b/src/Forms/Controls/MultiChoiceControl.php index b76fa6d3..e897933d 100644 --- a/src/Forms/Controls/MultiChoiceControl.php +++ b/src/Forms/Controls/MultiChoiceControl.php @@ -17,6 +17,8 @@ * * @property array $items * @property-read array $selectedItems + * + * @extends BaseControl */ abstract class MultiChoiceControl extends BaseControl { @@ -83,6 +85,7 @@ public function setValue($values): static /** * Returns selected keys. + * @return array-key[] */ public function getValue(): array { diff --git a/src/Forms/Controls/TextBase.php b/src/Forms/Controls/TextBase.php index b4363270..87b2fa3a 100644 --- a/src/Forms/Controls/TextBase.php +++ b/src/Forms/Controls/TextBase.php @@ -45,7 +45,6 @@ public function setValue($value): static /** * Returns control's value. - * @return mixed */ public function getValue(): mixed { diff --git a/tests/types/ControlsReturnTypeTest.php b/tests/types/ControlsReturnTypeTest.php new file mode 100644 index 00000000..8f6affad --- /dev/null +++ b/tests/types/ControlsReturnTypeTest.php @@ -0,0 +1,27 @@ + */ + public function dataFileAsserts(): iterable + { + yield from $this->gatherAssertTypes(__DIR__ . '/data/Controls.getValue().php'); + } + + + /** @dataProvider dataFileAsserts */ + public function testFileAsserts(string $assertType, string $file, mixed ...$args): void + { + $this->assertFileAsserts($assertType, $file, ...$args); + } +} + + +$testCase = new ControlsReturnTypeTest; +$testCase->run(); diff --git a/tests/types/TestCase.php b/tests/types/TestCase.php new file mode 100644 index 00000000..02f87fa4 --- /dev/null +++ b/tests/types/TestCase.php @@ -0,0 +1,28 @@ +addText('text'); +assertType('string|null', $input->getValue()); + +$input = $form->addPassword('password'); +assertType('string|null', $input->getValue()); + +$input = $form->addTextArea('textArea'); +assertType('string|null', $input->getValue()); + +$input = $form->addEmail('email'); +assertType('string|null', $input->getValue()); + +$input = $form->addInteger('integer'); +assertType('int|null', $input->getValue()); + +$input = $form->addFloat('float'); +assertType('float|null', $input->getValue()); + +$input = $form->addDate('date'); +assertType('DateTimeInterface|string|int|null', $input->getValue()); + +$input = $form->addTime('time'); +assertType('DateTimeInterface|string|int|null', $input->getValue()); + +$input = $form->addDateTime('dateTime'); +assertType('DateTimeInterface|string|int|null', $input->getValue()); + +$input = $form->addUpload('upload'); +assertType('array|Nette\Http\FileUpload|null', $input->getValue()); + +$input = $form->addMultiUpload('multiUpload'); +assertType('array|Nette\Http\FileUpload|null', $input->getValue()); + +$input = $form->addHidden('hidden'); +assertType('string|null', $input->getValue()); + +$input = $form->addCheckbox('checkbox'); +assertType('bool|null', $input->getValue()); + +$input = $form->addRadioList('radioList'); +assertType('int|string|null', $input->getValue()); + +$input = $form->addCheckboxList('checkboxList'); +assertType('array<(int|string)>', $input->getValue()); + +$input = $form->addSelect('select'); +assertType('int|string|null', $input->getValue()); + +$input = $form->addMultiSelect('multiSelect'); +assertType('array<(int|string)>', $input->getValue()); + +$input = $form->addColor('color'); +assertType('string|null', $input->getValue()); + +$input = $form->addSubmit('submit'); +assertType('string|null', $input->getValue()); + +$input = $form->addButton('button'); +assertType('string|null', $input->getValue()); + +$input = $form->addImageButton('imageButton'); +assertType('array|null', $input->getValue()); + +$input = $form->addImage('image'); +assertType('array|null', $input->getValue());