Skip to content

Commit

Permalink
[TASK] Extend route enhancer test framework
Browse files Browse the repository at this point in the history
* introduce `routeParameter` variable (default `{value}`)
* introduce ExceptionExpectation applicable in test cases
* adjust TestSet::getSingleApplicable($type) to consider
  ApplicableConjunction as well
* adjust configuration/declaration merges

Resolves: #90153
Releases: master, 9.5
Change-Id: Ic0e84ac91bb3a9f7a1d8b004052b8d93867a39e3
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63005
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
  • Loading branch information
ohader committed Jan 22, 2020
1 parent 98cbda1 commit 35386e5
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ public function localeModifierDataProvider($parentSet = null): array
// variables (applied when invoking expectations)
$variables = Variables::create()->define([
'value' => 100,
'resolveValue' => 100,
'routePrefix' => '{enhance_name}',
'aspectName' => 'enhance_name',
'inArguments' => 'dynamicArguments' // either 'dynamicArguments' or 'staticArguments'
Expand Down Expand Up @@ -248,6 +249,7 @@ public function persistedAliasMapperDataProvider($parentSet = null): array
// variables (applied when invoking expectations)
$variables = Variables::create()->define([
'value' => 1100,
'resolveValue' => 1100,
'routePrefix' => 'enhance',
'aspectName' => 'value',
'inArguments' => 'staticArguments' // either 'dynamicArguments' or 'staticArguments'
Expand Down Expand Up @@ -309,6 +311,7 @@ public function persistedPatternMapperDataProvider($parentSet = null): array
// variables (applied when invoking expectations)
$variables = Variables::create()->define([
'value' => 1100,
'resolveValue' => 1100,
'routePrefix' => 'enhance',
'aspectName' => 'value',
'inArguments' => 'staticArguments' // either 'dynamicArguments' or 'staticArguments'
Expand Down Expand Up @@ -370,6 +373,7 @@ public function staticValueMapperDataProvider($parentSet = null): array
// variables (applied when invoking expectations)
$variables = Variables::create()->define([
'value' => 100,
'resolveValue' => 100,
'routePrefix' => 'enhance',
'aspectName' => 'value',
'inArguments' => 'staticArguments' // either 'dynamicArguments' or 'staticArguments'
Expand Down Expand Up @@ -438,7 +442,10 @@ public function staticRangeMapperDataProvider($parentSet = null): array
$variableContexts = array_map(
function ($value) {
return VariablesContext::create(
Variables::create(['value' => $value])
Variables::create([
'value' => $value,
'resolveValue' => $value,
])
);
},
range(10, 100, 30)
Expand All @@ -447,7 +454,6 @@ function ($value) {
$builder = Builder::create();
// variables (applied when invoking expectations)
$variables = Variables::create()->define([
'value' => 1100,
'routePrefix' => 'enhance',
'aspectName' => 'value',
'inArguments' => 'staticArguments' // either 'dynamicArguments' or 'staticArguments'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ public static function create(): self
*/
public function declareEnhancers(): array
{
$routePath = VariableValue::create('/[[routePrefix]]/{value}');
$value = Variable::create('value', Variable::CAST_STRING);
$routePath = VariableValue::create(
'/[[routePrefix]]/[[routeParameter]]',
Variables::create(['routeParameter' => '{value}'])
);
$resolveValue = Variable::create('resolveValue', Variable::CAST_STRING);

return [
'Simple' => EnhancerDeclaration::create('Simple')
Expand All @@ -43,7 +46,7 @@ public function declareEnhancers(): array
])
->withResolveArguments([
VariableItem::create('inArguments', [
'value' => $value
'value' => $resolveValue
]),
]),
'Plugin' => EnhancerDeclaration::create('Plugin')
Expand All @@ -60,7 +63,7 @@ public function declareEnhancers(): array
->withResolveArguments([
VariableItem::create('inArguments', [
'testing' => [
'value' => $value,
'value' => $resolveValue,
],
]),
]),
Expand All @@ -85,7 +88,7 @@ public function declareEnhancers(): array
->withResolveArguments([
VariableItem::create('inArguments', [
'tx_testing_link' => [
'value' => $value,
'value' => $resolveValue,
],
]),
'staticArguments' => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,26 +74,44 @@ public function getGenerateParameters(): array
public function withConfiguration(array $configuration, bool $merge = false): self
{
$target = clone $this;
$target->configuration = $merge ? array_replace_recursive($this->configuration, $configuration) : $configuration;

$target->configuration = $merge ? $this->applyMergedItems($this->configuration, $configuration) : $configuration;
return $target;
}

public function withResolveArguments(array $resolveArguments, bool $merge = false): self
{
$target = clone $this;
$target->resolveArguments = $merge ? array_replace_recursive($this->resolveArguments, $resolveArguments) : $resolveArguments;
$target->resolveArguments = $merge ? $this->applyMergedItems($this->resolveArguments, $resolveArguments) : $resolveArguments;
return $target;
}

public function withGenerateParameters(array $generateParameters, bool $merge = false): self
{
$target = clone $this;
$target->generateParameters = $merge ? array_merge($this->generateParameters, $generateParameters) : $generateParameters;
$target->generateParameters = $merge ? $this->applyMergedItems($this->generateParameters, $generateParameters) : $generateParameters;
return $target;
}

public function describe(): string
{
return $this->identifier;
}

private function applyMergedItems(array $currentItems, array $additionalItems): array
{
if (empty($additionalItems)) {
return $currentItems;
}
if ($this->hasOnlyNumericKeys($additionalItems)) {
return array_merge($currentItems, $additionalItems);
}
return array_replace_recursive($currentItems, $additionalItems);
}

private function hasOnlyNumericKeys(array $items): bool
{
$numericItems = array_filter($items, 'is_int', ARRAY_FILTER_USE_KEY);
return !empty($numericItems);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php
declare(strict_types = 1);
namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Framework\Builder;

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

class ExceptionExpectation implements Applicable
{
/**
* @var string
*/
private $identifier;

/**
* @var string|null
*/
private $className;

/**
* @var int|null
*/
private $code;

/**
* @var string|null
*/
private $message;

public static function create(string $identifier): self
{
return new static($identifier);
}

private function __construct(string $identifier)
{
$this->identifier = $identifier;
}

public function withClassName(string $className): self
{
$target = clone $this;
$target->className = $className;
return $target;
}

public function withCode(int $code): self
{
$target = clone $this;
$target->code = $code;
return $target;
}

public function withMessage(string $message): self
{
$target = clone $this;
$target->message = $message;
return $target;
}

/**
* @return string|null
*/
public function getClassName(): ?string
{
return $this->className;
}

/**
* @return int|null
*/
public function getCode(): ?int
{
return $this->code;
}

/**
* @return string|null
*/
public function getMessage(): ?string
{
return $this->message;
}

public function describe(): string
{
return sprintf('Exception %s', $this->identifier);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,11 @@ public function withApplicableSet(Applicable ...$applicables): self
return $target;
}

public function withApplicableItems(array $applicables): self
public function withApplicableItems(array $applicableItems, Applicable ...$applicables): self
{
return $this->withApplicableSet(...array_values($applicables));
$applicableItems = array_values($applicableItems);
$applicableItems = array_merge($applicableItems, $applicables);
return $this->withApplicableSet(...$applicableItems);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,25 +70,12 @@ public function getApplicables(string $type = null): array
if ($type === null) {
return $this->applicables;
}
$applicables = [];
foreach ($this->applicables as $applicable) {
if (is_a($applicable, $type)) {
$applicables[] = $applicable;
} elseif ($applicable instanceof ApplicableConjunction) {
$applicables = array_merge($applicables, $applicable->filter($type));
}
}
return $applicables;
return $this->filterApplicables($type);
}

public function getSingleApplicable(string $type): ?Applicable
{
$applicables = array_filter(
$this->applicables,
function (Applicable $applicable) use ($type) {
return is_a($applicable, $type);
}
);
$applicables = $this->filterApplicables($type);
if (count($applicables) > 1) {
throw new \LogicException(
sprintf('Got %dx %s, expected one', count($applicables), $type),
Expand Down Expand Up @@ -155,4 +142,21 @@ function (Applicable $applicable) {
);
return 'pid: ' . $this->targetPageId . ' | ' . implode(' | ', $descriptions);
}

/**
* @param string $type
* @return Applicable[]
*/
private function filterApplicables(string $type): array
{
$applicables = [];
foreach ($this->applicables as $applicable) {
if (is_a($applicable, $type)) {
$applicables[] = $applicable;
} elseif ($applicable instanceof ApplicableConjunction) {
$applicables = array_merge($applicables, $applicable->filter($type));
}
}
return $applicables;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

class VariableItem
{
use VariablesTrait;

/**
* @var VariableValue
*/
Expand All @@ -27,6 +29,11 @@ class VariableItem
*/
private $value;

/**
* @var string[]
*/
private $requiredDefinedVariableNames;

public static function create(string $key, $value): self
{
return new static(
Expand All @@ -48,11 +55,17 @@ public function isArray(): bool

public function apply(Variables $variables): array
{
if (!$this->hasAllRequiredDefinedVariableNames($variables)) {
return [];
}
return [$this->key($variables) => $this->value];
}

public function key(Variables $variables): string
public function key(Variables $variables): ?string
{
if (!$this->hasAllRequiredDefinedVariableNames($variables)) {
return null;
}
return $this->variableKey->apply($variables);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

class VariableValue
{
use VariablesTrait;

/**
* @var string
*/
Expand Down Expand Up @@ -60,13 +62,6 @@ private function __construct(string $value, Variables $defaultVariables = null)
$this->defaultVariables = $defaultVariables;
}

public function withRequiredDefinedVariableNames(string ...$variableNames): self
{
$target = clone $this;
$target->requiredDefinedVariableNames = $variableNames;
return $target;
}

public function apply(Variables $variables): string
{
$variables = $variables->withDefined($this->defaultVariables);
Expand All @@ -83,18 +78,6 @@ public function apply(Variables $variables): string
);
}

private function hasAllRequiredDefinedVariableNames(Variables $variables): bool
{
foreach ($this->requiredDefinedVariableNames ?? [] as $variableName) {
if (!array_key_exists($variableName, $variables)
|| $variables[$variableName] === null
) {
return false;
}
}
return true;
}

private function assertVariableNames(Variables $variables): void
{
$missingVariableNames = array_diff($this->variableNames, $variables->keys());
Expand Down
Loading

0 comments on commit 35386e5

Please sign in to comment.