From 51e6a635db72723f773b826f96bd5353567829ba Mon Sep 17 00:00:00 2001 From: Mikael Meulle <21535-just_like_good_vibes@users.noreply.drupalcode.org> Date: Fri, 29 Nov 2024 08:00:57 +0000 Subject: [PATCH] Issue #3488879 by hctom, just_like_good_vibes, pdureau: Define typed_data support in enum PropType plugin definition --- .../src/Dummy/LinksSettingType.php | 4 +- src/EnumTrait.php | 11 +- .../PropType/AttributesPropType.php | 2 +- .../UiPatterns/PropType/BooleanPropType.php | 2 +- .../UiPatterns/PropType/EnumListPropType.php | 25 +++- .../UiPatterns/PropType/EnumPropType.php | 36 +++++- .../UiPatterns/PropType/EnumSetPropType.php | 11 +- .../UiPatterns/PropType/LinksPropType.php | 2 +- .../UiPatterns/PropType/SlotPropType.php | 2 +- .../UiPatterns/PropType/UrlPropType.php | 2 +- .../UiPatterns/Source/CheckboxesWidget.php | 2 +- src/Plugin/UiPatterns/Source/MenuSource.php | 2 +- src/Plugin/UiPatterns/Source/SelectWidget.php | 2 +- .../UiPatterns/Source/SelectsWidget.php | 2 +- src/PropTypeInterface.php | 7 +- src/PropTypePluginBase.php | 2 +- src/Template/TwigExtension.php | 2 +- tests/fixtures/EnumTestData.yml | 122 ++++++++++++++++++ tests/fixtures/TestDataSet.yml | 91 +++++++++++++ .../test-component.component.yml | 17 ++- .../test-component/test-component.twig | 10 ++ tests/src/Kernel/EnumNormalizationTest.php | 56 ++++++++ tests/src/Kernel/Source/SelectsWidgetTest.php | 24 ++++ tests/src/Traits/TestDataTrait.php | 2 +- 24 files changed, 413 insertions(+), 25 deletions(-) create mode 100644 tests/fixtures/EnumTestData.yml create mode 100644 tests/src/Kernel/EnumNormalizationTest.php create mode 100644 tests/src/Kernel/Source/SelectsWidgetTest.php diff --git a/modules/ui_patterns_legacy/src/Dummy/LinksSettingType.php b/modules/ui_patterns_legacy/src/Dummy/LinksSettingType.php index ff8cd9e37..9e6b1c054 100644 --- a/modules/ui_patterns_legacy/src/Dummy/LinksSettingType.php +++ b/modules/ui_patterns_legacy/src/Dummy/LinksSettingType.php @@ -18,11 +18,11 @@ class LinksSettingType { * normalize method was not part of any interface and not triggered by the * ComponentElementAlter yet. */ - public static function normalize(mixed $value): array { + public static function normalize(mixed $value, ?array $definition = NULL): array { $message = t("Deprecated call to LinksSettingType. If you manage some specific logic with it, replace it by LinksPropType. Otherwise, you can remove it because the render element is now taking care of the normalization."); \Drupal::logger('ui_patterns_legacy')->warning($message); \Drupal::service('messenger')->addWarning($message); - $value = LinksPropType::normalize($value); + $value = LinksPropType::normalize($value, $definition); return $value; } diff --git a/src/EnumTrait.php b/src/EnumTrait.php index 3d8bbfb16..cbbb3d3c2 100644 --- a/src/EnumTrait.php +++ b/src/EnumTrait.php @@ -12,7 +12,7 @@ trait EnumTrait { /** * Get form element options from enumeration. */ - protected function getEnumOptions(array $definition): array { + protected static function getEnumOptions(array $definition): array { $values = array_combine($definition['enum'], $definition['enum']); foreach ($values as $key => $label) { if (is_string($label)) { @@ -34,14 +34,14 @@ trait EnumTrait { /** * Get allowed values from enumeration. */ - protected function getAllowedValues(array $definition): array { - return array_values($this->getEnumOptions($definition)); + protected static function getAllowedValues(array $definition): array { + return array_values(static::getEnumOptions($definition)); } /** * Converts a source value type to enum data type. * - * @param string $value + * @param mixed $value * The stored. * @param array $enum * The defined enums. @@ -49,9 +49,10 @@ trait EnumTrait { * @return float|int|mixed * The converted value. */ - protected function convertValueToEnumType(string $value, array $enum) { + protected static function convertValueToEnumType(mixed $value, array $enum) { return match (TRUE) { in_array($value, $enum, TRUE) => $value, + in_array((string) $value, $enum, TRUE) => (string) $value, in_array((int) $value, $enum, TRUE) => (int) $value, in_array((float) $value, $enum, TRUE) => (float) $value, default => $value, diff --git a/src/Plugin/UiPatterns/PropType/AttributesPropType.php b/src/Plugin/UiPatterns/PropType/AttributesPropType.php index ef594e0c0..4890b40a8 100644 --- a/src/Plugin/UiPatterns/PropType/AttributesPropType.php +++ b/src/Plugin/UiPatterns/PropType/AttributesPropType.php @@ -47,7 +47,7 @@ class AttributesPropType extends PropTypePluginBase { /** * {@inheritdoc} */ - public static function normalize(mixed $value): array { + public static function normalize(mixed $value, ?array $definition = NULL): array { /* Attributes are defined as a mapping ('object' in JSON schema). So, source plugins are expected to return a mapping to not break SDC prop validation diff --git a/src/Plugin/UiPatterns/PropType/BooleanPropType.php b/src/Plugin/UiPatterns/PropType/BooleanPropType.php index 21a386ec3..25e74d25a 100644 --- a/src/Plugin/UiPatterns/PropType/BooleanPropType.php +++ b/src/Plugin/UiPatterns/PropType/BooleanPropType.php @@ -25,7 +25,7 @@ class BooleanPropType extends PropTypePluginBase { /** * {@inheritdoc} */ - public static function normalize(mixed $value): bool { + public static function normalize(mixed $value, ?array $definition = NULL): bool { return (bool) $value; } diff --git a/src/Plugin/UiPatterns/PropType/EnumListPropType.php b/src/Plugin/UiPatterns/PropType/EnumListPropType.php index 956b17681..e3042b96d 100644 --- a/src/Plugin/UiPatterns/PropType/EnumListPropType.php +++ b/src/Plugin/UiPatterns/PropType/EnumListPropType.php @@ -30,7 +30,7 @@ class EnumListPropType extends PropTypePluginBase { public function getSummary(array $definition): array { $summary = parent::getSummary($definition); if (isset($definition['items']['enum'])) { - $values = implode(", ", $this->getAllowedValues($definition['items'])); + $values = implode(", ", static::getAllowedValues($definition['items'])); $summary[] = $this->t("Allowed values: @values", ["@values" => $values]); } if (isset($definition['minItems'])) { @@ -42,4 +42,27 @@ class EnumListPropType extends PropTypePluginBase { return $summary; } + /** + * {@inheritdoc} + */ + public static function normalize(mixed $value, ?array $definition = NULL): mixed { + $value = parent::normalize($value, $definition); + if ($value === NULL) { + return []; + } + if (!is_array($value)) { + $value = [$value]; + } + if (!is_array($definition)) { + return $value; + } + $definition_items = $definition['items'] ?? []; + $value = array_map(function ($item) use ($definition_items) { + return EnumPropType::normalize($item, $definition_items); + }, $value); + return array_filter($value, function ($item) { + return $item !== NULL; + }); + } + } diff --git a/src/Plugin/UiPatterns/PropType/EnumPropType.php b/src/Plugin/UiPatterns/PropType/EnumPropType.php index 3c143449a..66c93d6e4 100644 --- a/src/Plugin/UiPatterns/PropType/EnumPropType.php +++ b/src/Plugin/UiPatterns/PropType/EnumPropType.php @@ -18,7 +18,9 @@ use Drupal\ui_patterns\PropTypePluginBase; description: new TranslatableMarkup('A single value restricted to a fixed set of values.'), default_source: 'select', schema: ['type' => ['string', 'number', 'integer'], 'enum' => []], - priority: 10 + priority: 10, + typed_data: ['float', 'integer', 'string'], + )] class EnumPropType extends PropTypePluginBase { @@ -30,10 +32,40 @@ class EnumPropType extends PropTypePluginBase { public function getSummary(array $definition): array { $summary = parent::getSummary($definition); if (isset($definition['enum'])) { - $values = implode(", ", $this->getAllowedValues($definition)); + $values = implode(", ", static::getAllowedValues($definition)); $summary[] = $this->t("Allowed values: @values", ["@values" => $values]); } return $summary; } + /** + * {@inheritdoc} + */ + public static function normalize(mixed $value, ?array $definition = NULL): mixed { + // @todo Change the autogenerated stub + $value = parent::normalize($value, $definition); + if (!is_array($definition)) { + return $value; + } + + $enum = $definition['enum'] ?? []; + if (!is_array($enum)) { + $enum = []; + } + // We try to match first without casting. + if (in_array($value, $enum, TRUE)) { + return $value; + } + // We try to cast the value and retry to match. + $value = static::convertValueToEnumType($value, $enum); + if (in_array($value, $enum, TRUE)) { + return $value; + } + // Fall back to default value (if defined) + if (isset($definition['default'])) { + return $definition['default']; + } + return NULL; + } + } diff --git a/src/Plugin/UiPatterns/PropType/EnumSetPropType.php b/src/Plugin/UiPatterns/PropType/EnumSetPropType.php index 58d158be4..66480ec64 100644 --- a/src/Plugin/UiPatterns/PropType/EnumSetPropType.php +++ b/src/Plugin/UiPatterns/PropType/EnumSetPropType.php @@ -37,7 +37,7 @@ class EnumSetPropType extends PropTypePluginBase { public function getSummary(array $definition): array { $summary = parent::getSummary($definition); if (isset($definition['items']['enum'])) { - $values = implode(", ", $this->getAllowedValues($definition['items'])); + $values = implode(", ", static::getAllowedValues($definition['items'])); $summary[] = $this->t("Allowed values: @values", ["@values" => $values]); } if (isset($definition['minItems'])) { @@ -49,4 +49,13 @@ class EnumSetPropType extends PropTypePluginBase { return $summary; } + /** + * {@inheritdoc} + */ + public static function normalize(mixed $value, ?array $definition = NULL): mixed { + $value = parent::normalize($value, $definition); + $value = EnumListPropType::normalize($value, $definition); + return is_array($value) ? array_unique($value) : []; + } + } diff --git a/src/Plugin/UiPatterns/PropType/LinksPropType.php b/src/Plugin/UiPatterns/PropType/LinksPropType.php index 1e29cafb6..972e90980 100644 --- a/src/Plugin/UiPatterns/PropType/LinksPropType.php +++ b/src/Plugin/UiPatterns/PropType/LinksPropType.php @@ -81,7 +81,7 @@ class LinksPropType extends PropTypePluginBase implements ContainerFactoryPlugin /** * {@inheritdoc} */ - public static function normalize(mixed $value): array { + public static function normalize(mixed $value, ?array $definition = NULL): array { if (!is_array($value)) { return []; } diff --git a/src/Plugin/UiPatterns/PropType/SlotPropType.php b/src/Plugin/UiPatterns/PropType/SlotPropType.php index 18f6911c9..a6fade789 100644 --- a/src/Plugin/UiPatterns/PropType/SlotPropType.php +++ b/src/Plugin/UiPatterns/PropType/SlotPropType.php @@ -28,7 +28,7 @@ class SlotPropType extends PropTypePluginBase { /** * {@inheritdoc} */ - public static function normalize(mixed $value): mixed { + public static function normalize(mixed $value, ?array $definition = NULL): mixed { if (is_object($value)) { return self::convertObject($value); } diff --git a/src/Plugin/UiPatterns/PropType/UrlPropType.php b/src/Plugin/UiPatterns/PropType/UrlPropType.php index 17cfd72e2..47d31ccac 100644 --- a/src/Plugin/UiPatterns/PropType/UrlPropType.php +++ b/src/Plugin/UiPatterns/PropType/UrlPropType.php @@ -26,7 +26,7 @@ class UrlPropType extends PropTypePluginBase { /** * {@inheritdoc} */ - public static function normalize(mixed $value): string { + public static function normalize(mixed $value, ?array $definition = NULL): string { if (is_a($value, '\Drupal\Core\Url')) { $value = $value->toString(); } diff --git a/src/Plugin/UiPatterns/Source/CheckboxesWidget.php b/src/Plugin/UiPatterns/Source/CheckboxesWidget.php index 3f6fee4b0..1668ebe99 100644 --- a/src/Plugin/UiPatterns/Source/CheckboxesWidget.php +++ b/src/Plugin/UiPatterns/Source/CheckboxesWidget.php @@ -41,7 +41,7 @@ class CheckboxesWidget extends SourcePluginPropValue { $form['value'] = [ '#type' => 'checkboxes', '#default_value' => $this->getSetting('value') ?? [], - "#options" => $this->getEnumOptions($this->propDefinition['items']), + "#options" => static::getEnumOptions($this->propDefinition['items']), ]; $this->addRequired($form['value']); return $form; diff --git a/src/Plugin/UiPatterns/Source/MenuSource.php b/src/Plugin/UiPatterns/Source/MenuSource.php index 395b519f2..5c367584c 100644 --- a/src/Plugin/UiPatterns/Source/MenuSource.php +++ b/src/Plugin/UiPatterns/Source/MenuSource.php @@ -174,7 +174,7 @@ class MenuSource extends SourcePluginBase { "items" => $tree["#items"], ]; $this->moduleHandler->invokeAll("preprocess_menu", [&$variables]); - $variables["items"] = LinksPropType::normalize($variables["items"]); + $variables["items"] = LinksPropType::normalize($variables["items"], $this->getPropDefinition()); return $variables["items"]; } return []; diff --git a/src/Plugin/UiPatterns/Source/SelectWidget.php b/src/Plugin/UiPatterns/Source/SelectWidget.php index e593bdfcb..39665421b 100644 --- a/src/Plugin/UiPatterns/Source/SelectWidget.php +++ b/src/Plugin/UiPatterns/Source/SelectWidget.php @@ -32,7 +32,7 @@ class SelectWidget extends SourcePluginPropValue { $form['value'] = [ '#type' => 'select', '#default_value' => $this->getSetting('value'), - "#options" => $this->getEnumOptions($this->propDefinition), + "#options" => static::getEnumOptions($this->propDefinition), "#empty_option" => $this->t("- Select -"), ]; $this->addRequired($form['value']); diff --git a/src/Plugin/UiPatterns/Source/SelectsWidget.php b/src/Plugin/UiPatterns/Source/SelectsWidget.php index 3543aae8d..9989bd16a 100644 --- a/src/Plugin/UiPatterns/Source/SelectsWidget.php +++ b/src/Plugin/UiPatterns/Source/SelectsWidget.php @@ -44,7 +44,7 @@ class SelectsWidget extends SourcePluginPropValue { $form['value'][$index] = [ '#type' => 'select', '#default_value' => $this->getSetting('value')[$index] ?? NULL, - '#options' => $this->getEnumOptions($this->propDefinition['items']), + '#options' => static::getEnumOptions($this->propDefinition['items']), '#title' => '#' . ($index + 1), '#required' => ($index < $min), '#empty_value' => "", diff --git a/src/PropTypeInterface.php b/src/PropTypeInterface.php index 76db6c5a7..1b04d2f22 100644 --- a/src/PropTypeInterface.php +++ b/src/PropTypeInterface.php @@ -46,10 +46,15 @@ interface PropTypeInterface extends WithJsonSchemaInterface, PluginInspectionInt /** * Normalize the prop type value before validation. * + * @param mixed $value + * The value to normalize. + * @param array|null $definition + * The prop type definition. + * * @return mixed * The JSON schema valid prop type value. */ - public static function normalize(mixed $value): mixed; + public static function normalize(mixed $value, ?array $definition = NULL): mixed; /** * Preprocess the prop type value before the rendering. diff --git a/src/PropTypePluginBase.php b/src/PropTypePluginBase.php index 0a5f9582b..6cbca60dc 100644 --- a/src/PropTypePluginBase.php +++ b/src/PropTypePluginBase.php @@ -64,7 +64,7 @@ abstract class PropTypePluginBase extends PluginBase implements PropTypeInterfac /** * {@inheritdoc} */ - public static function normalize(mixed $value): mixed { + public static function normalize(mixed $value, ?array $definition = NULL): mixed { return $value; } diff --git a/src/Template/TwigExtension.php b/src/Template/TwigExtension.php index b9cdf10a8..95f316027 100644 --- a/src/Template/TwigExtension.php +++ b/src/Template/TwigExtension.php @@ -132,7 +132,7 @@ class TwigExtension extends AbstractExtension { continue; } $prop_type = $props[$variable]['ui_patterns']['type_definition']; - $context[$variable] = $prop_type->normalize($value); + $context[$variable] = $prop_type->normalize($value, $props[$variable]); if (isset($props[$variable]['ui_patterns']['prop_type_adapter'])) { $prop_type_adapter_id = $props[$variable]['ui_patterns']['prop_type_adapter']; /** @var \Drupal\ui_patterns\PropTypeAdapterInterface $prop_type_adapter */ diff --git a/tests/fixtures/EnumTestData.yml b/tests/fixtures/EnumTestData.yml new file mode 100644 index 000000000..d9b4cdd70 --- /dev/null +++ b/tests/fixtures/EnumTestData.yml @@ -0,0 +1,122 @@ +test_0: + render: + "#type": "inline_template" + "#template": '{{ include("ui_patterns_test:test-component", { "enum_integer": enum_integer}) }}' + '#context': + enum_integer: 2 + expected: + assert: assertStringContainsString + rendered_value: '<div class="ui-patterns-props-enum_integer">2</div>' + +test_0_1: + render: + "#type": "inline_template" + "#template": '{{ include("ui_patterns_test:test-component", { "enum_integer": enum_integer}) }}' + '#context': + enum_integer: "2" + expected: + assert: assertStringContainsString + rendered_value: '<div class="ui-patterns-props-enum_integer">2</div>' + +# when a bad value is injected, an exception will be thrown +#test_0_2: +# render: +# "#type": "inline_template" +# "#template": '{{ include("ui_patterns_test:test-component", { "enum_integer": enum_integer}) }}' +# '#context': +# enum_integer: "BAD" +# expected: +# assert: assertStringContainsString +# rendered_value: '<div class="ui-patterns-props-enum_integer">2</div>' + + +test_1: + render: + "#type": "inline_template" + "#template": '{{ include("ui_patterns_test:test-component", { "enum_list_multiple": enum_list_multiple}) }}' + '#context': + enum_list_multiple: [2] + expected: + assert: assertStringContainsString + rendered_value: '<div class="ui-patterns-props-enum_list_multiple"><span>2</span></div>' + +test_2: + render: + "#type": "inline_template" + "#template": '{{ include("ui_patterns_test:test-component", {"enum_set": enum_set }) }}' + '#context': + enum_set: [2] + expected: + assert: assertStringContainsString + rendered_value: '<div class="ui-patterns-props-enum_set"><span>2</span></div>' + +test_1_1: + render: + "#type": "inline_template" + "#template": '{{ include("ui_patterns_test:test-component", { "enum_list_multiple": enum_list_multiple}) }}' + '#context': + enum_list_multiple: ["2"] + expected: + assert: assertStringContainsString + rendered_value: '<div class="ui-patterns-props-enum_list_multiple"><span>2</span></div>' + +test_2_1: + render: + "#type": "inline_template" + "#template": '{{ include("ui_patterns_test:test-component", {"enum_set": enum_set }) }}' + '#context': + enum_set: ["2"] + expected: + assert: assertStringContainsString + rendered_value: '<div class="ui-patterns-props-enum_set"><span>2</span></div>' + +test_1_2: + render: + "#type": "inline_template" + "#template": '{{ include("ui_patterns_test:test-component", { "enum_list_multiple": enum_list_multiple}) }}' + '#context': + enum_list_multiple: "2" + expected: + assert: assertStringContainsString + rendered_value: '<div class="ui-patterns-props-enum_list_multiple"><span>2</span></div>' + +test_2_2: + render: + "#type": "inline_template" + "#template": '{{ include("ui_patterns_test:test-component", {"enum_set": enum_set }) }}' + '#context': + enum_set: "2" + expected: + assert: assertStringContainsString + rendered_value: '<div class="ui-patterns-props-enum_set"><span>2</span></div>' + + +test_3: + render: + "#type": "inline_template" + "#template": '{{ include("ui_patterns_test:test-component", { "enum_list_multiple": enum_list_multiple}) }}' + '#context': + enum_list_multiple: [2, 2, 2] + expected: + assert: assertStringContainsString + rendered_value: '<div class="ui-patterns-props-enum_list_multiple"><span>2</span><span>2</span><span>2</span></div>' + +test_4: + render: + "#type": "inline_template" + "#template": '{{ include("ui_patterns_test:test-component", { "enum_list_multiple": enum_list_multiple}) }}' + '#context': + enum_list_multiple: [2, "BADD", 2, 2, 444, "BAD"] + expected: + assert: assertStringContainsString + rendered_value: '<div class="ui-patterns-props-enum_list_multiple"><span>2</span><span>2</span><span>2</span></div>' + +test_5: + render: + "#type": "inline_template" + "#template": '{{ include("ui_patterns_test:test-component", {"enum_set": enum_set }) }}' + '#context': + enum_set: [2, 2, 2] + expected: + assert: assertStringContainsString + rendered_value: '<div class="ui-patterns-props-enum_set"><span>2</span></div>' diff --git a/tests/fixtures/TestDataSet.yml b/tests/fixtures/TestDataSet.yml index 403138776..1f6e35fae 100644 --- a/tests/fixtures/TestDataSet.yml +++ b/tests/fixtures/TestDataSet.yml @@ -144,6 +144,97 @@ select_string: enum_string: normalized_value: '2' entity: {} + +selects_1: + component: + component_id: ui_patterns_test:test-component + props: + enum_list_multiple: + source_id: selects + source: + value: 2 + enum_set: + source_id: selects + source: + value: 2 + output: + props: + enum_list_multiple: + same: + - 2 + enum_set: + same: + - 2 + entity: {} + + +selects_2: + component: + component_id: ui_patterns_test:test-component + props: + enum_list_multiple: + source_id: selects + source: + value: "2" + enum_set: + source_id: selects + source: + value: "2" + output: + props: + enum_list_multiple: + same: + - "2" + enum_set: + same: + - "2" + +selects_3: + component: + component_id: ui_patterns_test:test-component + props: + enum_list_multiple: + source_id: selects + source: + value: [2] + enum_set: + source_id: selects + source: + value: [2] + output: + props: + enum_list_multiple: + same: + - 2 + enum_set: + same: + - 2 + +selects_4: + component: + component_id: ui_patterns_test:test-component + props: + enum_list_multiple: + source_id: selects + source: + value: [2, 2, 2] + enum_set: + source_id: selects + source: + value: 2 + output: + props: + enum_list_multiple: + same: + - 2 + - 2 + - 2 + enum_set: + same: + - 2 + + + token_default: component: component_id: ui_patterns_test:test-component diff --git a/tests/modules/ui_patterns_test/components/test-component/test-component.component.yml b/tests/modules/ui_patterns_test/components/test-component/test-component.component.yml index 83fb58fa8..756c1fb9e 100644 --- a/tests/modules/ui_patterns_test/components/test-component/test-component.component.yml +++ b/tests/modules/ui_patterns_test/components/test-component/test-component.component.yml @@ -37,7 +37,7 @@ props: enum: - "2" - "3" - enum_list : + enum_list: title: 'Enum List' $ref: 'ui-patterns://enum_list' items: @@ -47,6 +47,21 @@ props: 'meta:enum': A: 'Label A' B: 'Label B' + enum_list_multiple: + title: "Enum List" + type: array + maxItems: 3 + items: + type: integer + enum: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ] + enum_set: + title: "Enum Set" + type: array + uniqueItems: true + maxItems: 3 + items: + type: integer + enum: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ] list_string: title: "List String" type: "array" diff --git a/tests/modules/ui_patterns_test/components/test-component/test-component.twig b/tests/modules/ui_patterns_test/components/test-component/test-component.twig index 0870e6979..10ff70a2d 100644 --- a/tests/modules/ui_patterns_test/components/test-component/test-component.twig +++ b/tests/modules/ui_patterns_test/components/test-component/test-component.twig @@ -41,6 +41,16 @@ <span>{{ item }}</span> {% endfor %} </div> + <div class="ui-patterns-props-enum_list_multiple"> + {% for item in enum_list_multiple %} + <span>{{ item }}</span> + {% endfor %} + </div> + <div class="ui-patterns-props-enum_set"> + {% for item in enum_set %} + <span>{{ item }}</span> + {% endfor %} + </div> <div class="ui-patterns-props-list_string"> {% for item in list_string %} <span>{{ item }}</span> diff --git a/tests/src/Kernel/EnumNormalizationTest.php b/tests/src/Kernel/EnumNormalizationTest.php new file mode 100644 index 000000000..dd865640f --- /dev/null +++ b/tests/src/Kernel/EnumNormalizationTest.php @@ -0,0 +1,56 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel; + +use Drupal\KernelTests\KernelTestBase; +use Drupal\Tests\ui_patterns\Traits\TestDataTrait; + +/** + * Base class to test source plugins. + * + * @group ui_patterns + */ +class EnumNormalizationTest extends KernelTestBase { + + use TestDataTrait; + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'system', + 'user', + 'text', + 'field', + 'node', + 'ui_patterns', + 'ui_patterns_test', + 'datetime', + 'filter', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + $this->installSchema('node', 'node_access'); + $this->installEntitySchema('node'); + $this->installEntitySchema('user'); + $this->installConfig(['system', 'filter']); + } + + /** + * Test attributes. + */ + public function testAttributes() : void { + $testData = self::loadTestDataFixture(__DIR__ . "/../../fixtures/EnumTestData.yml"); + $testSets = $testData->getTestSets(); + foreach ($testSets as $test_set_name => $test_set) { + $this->assertExpectedOutput($test_set["expected"], $test_set["render"]); + } + } + +} diff --git a/tests/src/Kernel/Source/SelectsWidgetTest.php b/tests/src/Kernel/Source/SelectsWidgetTest.php new file mode 100644 index 000000000..2d30ed5ea --- /dev/null +++ b/tests/src/Kernel/Source/SelectsWidgetTest.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test SelectsWidget. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\SelectWidget + * @group ui_patterns + */ +class SelectsWidgetTest extends SourcePluginsTestBase { + + /** + * Test SelectWidget Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('selects_'); + } + +} diff --git a/tests/src/Traits/TestDataTrait.php b/tests/src/Traits/TestDataTrait.php index 693e50b60..563cb492b 100644 --- a/tests/src/Traits/TestDataTrait.php +++ b/tests/src/Traits/TestDataTrait.php @@ -68,7 +68,7 @@ trait TestDataTrait { $assert_done = TRUE; } if (isset($expected_result['normalized_value'])) { - $normalized_value = self::normalizeMarkupString($result); + $normalized_value = self::normalizeMarkupString((string) $result); $this->assertTrue(str_contains($normalized_value, $expected_result['normalized_value']), sprintf("%s: '%s'", $message, $normalized_value)); $assert_done = TRUE; } -- GitLab