Skip to content

Commit

Permalink
Add tests for key merging
Browse files Browse the repository at this point in the history
  • Loading branch information
mpdude committed Oct 7, 2024
1 parent aef2551 commit cf673c1
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 15 deletions.
33 changes: 21 additions & 12 deletions extra/html-extra/HtmlExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
use Twig\Environment;
use Twig\Error\RuntimeError;
use Twig\Extension\AbstractExtension;
use Twig\Extension\CoreExtension;
use Twig\Extension\EscaperExtension;
use Twig\Runtime\EscaperRuntime;
use Twig\TwigFilter;
use Twig\TwigFunction;
Expand Down Expand Up @@ -144,21 +142,32 @@ public static function htmlAttrMerge(...$arrays): array
throw new RuntimeError(sprintf('The "attr_merge" filter only works with arrays or "Traversable", got "%s" for argument %d.', \gettype($array), $argNumber + 1));
}

$array = CoreExtension::toArray($array);
$array = (array) ($array);

foreach (['class', 'style', 'data', 'aria'] as $deepMergeKey) {
if (isset($array[$deepMergeKey])) {
$value = $array[$deepMergeKey];
unset($array[$deepMergeKey]);
foreach (['data', 'aria'] as $flatOutKey) {
if (!isset($array[$flatOutKey])) {
continue;
}
$values = (array) $array[$flatOutKey];
foreach ($values as $key => $value) {
$result[$flatOutKey.'-'.$key] = $value;
}
unset($array[$flatOutKey]);
}

if (!is_iterable($value)) {
$value = (array) $value;
}
foreach (['class', 'style'] as $deepMergeKey) {
if (!isset($array[$deepMergeKey])) {
continue;
}

$value = CoreExtension::toArray($value);
$value = $array[$deepMergeKey];
unset($array[$deepMergeKey]);

$result[$deepMergeKey] = array_merge($result[$deepMergeKey] ?? [], $value);
if (!is_iterable($value)) {
$value = (array) $value;
}

$result[$deepMergeKey] = array_merge($result[$deepMergeKey] ?? [], $value);
}

$result = array_merge($result, $array);
Expand Down
145 changes: 142 additions & 3 deletions extra/html-extra/Tests/HtmlAttrMergeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,150 @@ public function testMerge(array $expected, array $inputs): void

public function htmlAttrProvider(): \Generator
{
yield 'simple test' => [
['id' => 'some-id', 'class' => ['some-class']],
yield 'merging different attributes from two arrays' => [
['id' => 'some-id', 'label' => 'some-label'],
[
['id' => 'some-id'],
['class' => 'some-class'],
['label' => 'some-label'],
]
];

yield 'merging different attributes from three arrays' => [
['id' => 'some-id', 'label' => 'some-label', 'role' => 'main'],
[
['id' => 'some-id'],
['label' => 'some-label'],
['role' => 'main'],
]
];

yield 'merging different attributes from Traversables' => [
['id' => 'some-id', 'label' => 'some-label', 'role' => 'main'],
[
new \ArrayIterator(['id' => 'some-id']),
new \ArrayIterator(['label' => 'some-label']),
new \ArrayIterator(['role' => 'main']),
]
];

yield 'later keys override previous ones' => [
['id' => 'other'],
[
['id' => 'this'],
['id' => 'that'],
['id' => 'other'],
]
];

yield 'ignore empty strings or arrays passed as arguments' => [
['some' => 'attribute'],
[
['some' => 'attribute'],
[], // empty array
'', // empty string
]
];

yield 'keep "true" and "false" boolean values' => [
['disabled' => true, 'enabled' => false],
[
['disabled' => true],
['enabled' => false],
]
];

yield 'consolidate values for the "class" key' => [
['class' => ['foo', 'bar', 'baz']],
[
['class' => ['foo']],
['class' => 'bar'], // string, not array
['class' => ['baz']],
]
];

yield 'class values can be overridden when they use names (array keys)' => [
['class' => ['foo', 'bar', 'importance' => 'high']],
[
['class' => 'foo'],
['class' => ['bar', 'importance' => 'low']],
['class' => ['importance' => 'high']],
]
];

yield 'inline style values with numerical keys are merely collected' => [
['style' => ['font-weight: light', 'color: green', 'font-weight: bold']],
[
['style' => ['font-weight: light']],
['style' => ['color: green', 'font-weight: bold']],
]
];

yield 'inline style values can be overridden when they use names (array keys)' => [
['style' => ['font-weight' => 'bold', 'color' => 'red']],
[
['style' => ['font-weight' => 'light']],
['style' => ['color' => 'green', 'font-weight' => 'bold']],
['style' => ['color' => 'red']],
]
];

yield 'no merging happens when mixing numerically indexed inline styles with named ones' => [
['style' => ['color: green', 'color' => 'red']],
[
['style' => ['color: green']],
['style' => ['color' => 'red']],
]
];

yield 'turning aria attributes from array to flat keys' => [
['aria-role' => 'banner'],
[
['aria' => ['role' => 'main']],
['aria' => ['role' => 'banner']],
]
];

yield 'merging aria attributes, where the array values overrides the flat one' => [
['aria-role' => 'navigation'],
[
['aria-role' => 'main'],
['aria' => ['role' => 'banner']],
['aria' => ['role' => 'navigation']],
]
];

yield 'merging aria attributes, where the flat ones overrides the array' => [
['aria-role' => 'navigation'],
[
['aria' => ['role' => 'main']],
['aria-role' => 'banner'],
['aria-role' => 'navigation'],
]
];

yield 'turning data attributes from array to flat keys' => [
['data-test' => 'bar'],
[
['data' => ['test' => 'foo']],
['data' => ['test' => 'bar']],
]
];

yield 'merging data attributes, where the array values overrides the flat one' => [
['data-test' => 'baz'],
[
['data-test' => 'foo'],
['data' => ['test' => 'bar']],
['data' => ['test' => 'baz']],
]
];

yield 'merging data attributes, where the flat ones overrides the array' => [
['data-test' => 'baz'],
[
['data' => ['test' => 'foo']],
['data-test' => 'bar'],
['data-test' => 'baz'],
]
];
}
Expand Down

0 comments on commit cf673c1

Please sign in to comment.