diff --git a/CHANGELOG.md b/CHANGELOG.md index ca1822a..65d5b3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Common and useful classes, methods, exceptions etc. 1. Tests > refactoring & minor improvements 2. Utilities > CssSelector > useful methods related to CSS selectors +3. Utilities > Bootstrap4CssSelector > useful methods related to CSS selectors and the Bootstrap4 (front-end component library) # 0.1.2 diff --git a/src/Utilities/Bootstrap4CssSelector.php b/src/Utilities/Bootstrap4CssSelector.php new file mode 100644 index 0000000..6933274 --- /dev/null +++ b/src/Utilities/Bootstrap4CssSelector.php @@ -0,0 +1,85 @@ + + * @copyright Meritoo + */ +class Bootstrap4CssSelector +{ + /** + * Returns selector of container with field's validation error + * + * @return string + */ + public static function getFieldErrorContainerSelector() + { + return '.invalid-feedback .form-error-message'; + } + + /** + * Returns selector of field's validation error + * + * @param string $formName Name of form (value of the "name" attribute) + * @param string $fieldId ID of field (value of the "id" attribute) + * @return string + */ + public static function getFieldErrorSelector($formName, $fieldId) + { + $labelSelector = CssSelector::getLabelSelector($formName, $fieldId); + + if (empty($labelSelector)) { + return ''; + } + + $errorContainerSelector = static::getFieldErrorContainerSelector(); + + return sprintf('%s %s', $labelSelector, $errorContainerSelector); + } + + /** + * Returns selector of radio-button's validation error + * + * @param string $formName Name of form (value of the "name" attribute) + * @param int $fieldSetIndex Index/Position of the field-set + * @return string + */ + public static function getRadioButtonErrorSelector($formName, $fieldSetIndex) + { + $fieldSetSelector = CssSelector::getFieldSetByIndexSelector($formName, $fieldSetIndex); + + if (empty($fieldSetSelector)) { + return ''; + } + + $errorContainerSelector = static::getFieldErrorContainerSelector(); + + return sprintf('%s legend.col-form-label %s', $fieldSetSelector, $errorContainerSelector); + } + + /** + * Returns selector of field's group + * + * @param string $formName Name of form (value of the "name" attribute) + * @return string + */ + public static function getFieldGroupSelector($formName) + { + $formSelector = CssSelector::getFormByNameSelector($formName); + + if (empty($formSelector)) { + return ''; + } + + return sprintf('%s .form-group', $formSelector); + } +} diff --git a/tests/Utilities/Bootstrap4CssSelectorTest.php b/tests/Utilities/Bootstrap4CssSelectorTest.php new file mode 100644 index 0000000..c2aa462 --- /dev/null +++ b/tests/Utilities/Bootstrap4CssSelectorTest.php @@ -0,0 +1,185 @@ + + * @copyright Meritoo + */ +class Bootstrap4CssSelectorTest extends BaseTestCase +{ + public function testConstructor() + { + static::assertHasNoConstructor(Bootstrap4CssSelector::class); + } + + /** + * @param string $emptyValue Name of form (value of the "name" attribute) + * @dataProvider provideEmptyScalarValue + */ + public function testGetRadioButtonErrorSelectorUsingEmptyFormName($emptyValue) + { + $fieldSetIndex = 1; + static::assertSame('', Bootstrap4CssSelector::getRadioButtonErrorSelector($emptyValue, $fieldSetIndex)); + } + + public function testGetRadioButtonErrorSelectorUsingNegativeFieldSetIndex() + { + static::assertSame('', Bootstrap4CssSelector::getRadioButtonErrorSelector('test-test', -1)); + } + + /** + * @param string $formName Name of form (value of the "name" attribute) + * @param int $fieldSetIndex Index/Position of the field-set + * @param string $expected Expected selector + * + * @dataProvider provideFormNameFieldSetIndexAndSelector + */ + public function testGetRadioButtonErrorSelector($formName, $fieldSetIndex, $expected) + { + static::assertSame($expected, Bootstrap4CssSelector::getRadioButtonErrorSelector($formName, $fieldSetIndex)); + } + + /** + * @param string $emptyValue Name of form (value of the "name" attribute) + * @dataProvider provideEmptyScalarValue + */ + public function testGetFieldErrorSelectorUsingEmptyFormName($emptyValue) + { + $fieldName = 'test'; + static::assertSame('', Bootstrap4CssSelector::getFieldErrorSelector($emptyValue, $fieldName)); + } + + /** + * @param string $emptyValue Name of field (value of the "name" attribute) + * @dataProvider provideEmptyScalarValue + */ + public function testGetFieldErrorSelectorUsingEmptyFieldName($emptyValue) + { + $formName = 'test'; + static::assertSame('', Bootstrap4CssSelector::getFieldErrorSelector($formName, $emptyValue)); + } + + /** + * @param string $formName Name of form (value of the "name" attribute) + * @param string $fieldName Name of field (value of the "name" attribute) + * @param string $expected Expected selector + * + * @dataProvider provideFormNameFieldNameAndSelector + */ + public function testGetFieldErrorSelector($formName, $fieldName, $expected) + { + static::assertSame($expected, Bootstrap4CssSelector::getFieldErrorSelector($formName, $fieldName)); + } + + /** + * @param string $emptyValue Name of form (value of the "name" attribute) + * @dataProvider provideEmptyScalarValue + */ + public function testGetFieldGroupSelectorUsingEmptyFormName($emptyValue) + { + static::assertSame('', Bootstrap4CssSelector::getFieldGroupSelector($emptyValue)); + } + + /** + * @param string $formName Name of form (value of the "name" attribute) + * @param string $expected Expected selector + * + * @dataProvider provideFormNameAndSelector + */ + public function testGetFieldGroupSelector($formName, $expected) + { + static::assertSame($expected, Bootstrap4CssSelector::getFieldGroupSelector($formName)); + } + + public function testGetFieldErrorContainerSelector() + { + static::assertSame('.invalid-feedback .form-error-message', Bootstrap4CssSelector::getFieldErrorContainerSelector()); + } + + /** + * Provides name of form, index/position of the field-set and expected selector + * + * @return \Generator + */ + public function provideFormNameFieldSetIndexAndSelector() + { + yield[ + 'test', + 0, + 'form[name="test"] fieldset:nth-of-type(0) legend.col-form-label .invalid-feedback .form-error-message', + ]; + + yield[ + 'test-123-test-456', + 1, + 'form[name="test-123-test-456"] fieldset:nth-of-type(1) legend.col-form-label .invalid-feedback .form-error-message', + ]; + + yield[ + 'test_something_098_different', + 1245, + 'form[name="test_something_098_different"] fieldset:nth-of-type(1245) legend.col-form-label .invalid-feedback .form-error-message', + ]; + } + + /** + * Provides name of form, name of field and expected selector + * + * @return \Generator + */ + public function provideFormNameFieldNameAndSelector() + { + yield[ + 'test', + 'test', + 'form[name="test"] label[for="test"] .invalid-feedback .form-error-message', + ]; + + yield[ + 'test-123-test-456', + 'great-000-field', + 'form[name="test-123-test-456"] label[for="great-000-field"] .invalid-feedback .form-error-message', + ]; + + yield[ + 'test_something_098_different', + 'this-is-the-123789-field', + 'form[name="test_something_098_different"] label[for="this-is-the-123789-field"] .invalid-feedback .form-error-message', + ]; + } + + /** + * Provides name of form and expected selector + * + * @return \Generator + */ + public function provideFormNameAndSelector() + { + yield[ + 'test', + 'form[name="test"] .form-group', + ]; + + yield[ + 'test-123-test-456', + 'form[name="test-123-test-456"] .form-group', + ]; + + yield[ + 'test_something_098_different', + 'form[name="test_something_098_different"] .form-group', + ]; + } +}