-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
18 changed files
with
712 additions
and
495 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Qameta\Allure\PHPUnit\Internal; | ||
|
||
use Qameta\Allure\Hook\LifecycleHookInterface; | ||
use Qameta\Allure\PHPUnit\Setup\ThreadDetectorInterface; | ||
use Qameta\Allure\Setup\LinkTemplateInterface; | ||
use RuntimeException; | ||
|
||
use function class_exists; | ||
use function is_a; | ||
use function is_array; | ||
use function is_callable; | ||
use function is_int; | ||
use function is_string; | ||
|
||
final class Config implements ConfigInterface | ||
{ | ||
public function __construct( | ||
private array $data, | ||
) { | ||
} | ||
|
||
public function getOutputDirectory(): ?string | ||
{ | ||
$key = 'outputDirectory'; | ||
if (!isset($this->data[$key])) { | ||
return null; | ||
} | ||
|
||
/** @psalm-var mixed $outputDirectory */ | ||
$outputDirectory = $this->data[$key]; | ||
|
||
return is_string($outputDirectory) | ||
? $outputDirectory | ||
: throw new RuntimeException("Config key \"{$key}\" should contain a string"); | ||
} | ||
|
||
/** | ||
* @return array<string, LinkTemplateInterface> | ||
*/ | ||
public function getLinkTemplates(): array | ||
{ | ||
$key = 'linkTemplates'; | ||
$linkTemplates = []; | ||
/** @psalm-var mixed $linkTemplateSource */ | ||
foreach ($this->getArrayFromData($key) as $linkKey => $linkTemplateSource) { | ||
if (!is_string($linkKey)) { | ||
throw new RuntimeException( | ||
"Config key \"{$key}\" should contain an array with string keys only", | ||
); | ||
} | ||
$linkTemplates[$linkKey] = $this->buildObject( | ||
"{$key}/{$linkKey}", | ||
$linkTemplateSource, | ||
LinkTemplateInterface::class, | ||
); | ||
} | ||
|
||
return $linkTemplates; | ||
} | ||
|
||
private function getArrayFromData(string $key): array | ||
{ | ||
/** @psalm-var mixed $source */ | ||
$source = $this->data[$key] ?? []; | ||
|
||
return is_array($source) | ||
? $source | ||
: throw new RuntimeException("Config key \"{$key}\" should contain an array"); | ||
} | ||
|
||
/** | ||
* @template T | ||
* @param string $key | ||
* @param mixed $source | ||
* @param class-string<T> $expectedClass | ||
* @return T | ||
* @psalm-suppress MixedMethodCall | ||
*/ | ||
private function buildObject(string $key, mixed $source, string $expectedClass): object | ||
{ | ||
return match (true) { | ||
$source instanceof $expectedClass => $source, | ||
$this->isExpectedClassName($source, $expectedClass) => new $source(), | ||
is_callable($source) => $this->buildObject($key, $source(), $expectedClass), | ||
default => throw new RuntimeException( | ||
"Config key \"{$key}\" contains invalid source of {$expectedClass}", | ||
), | ||
}; | ||
} | ||
|
||
/** | ||
* @template T | ||
* @param mixed $source | ||
* @param class-string<T> $expectedClass | ||
* @return bool | ||
* @psalm-assert-if-true class-string<T> $source | ||
*/ | ||
private function isExpectedClassName(mixed $source, string $expectedClass): bool | ||
{ | ||
return $this->isClassName($source) && is_a($source, $expectedClass, true); | ||
} | ||
|
||
/** | ||
* @psalm-assert-if-true class-string $source | ||
*/ | ||
private function isClassName(mixed $source): bool | ||
{ | ||
return is_string($source) && class_exists($source); | ||
} | ||
|
||
public function getSetupHook(): ?callable | ||
{ | ||
$key = 'setupHook'; | ||
/** @psalm-var mixed $source */ | ||
$source = $this->data[$key] ?? null; | ||
|
||
return isset($source) | ||
? $this->buildCallable($key, $source) | ||
: null; | ||
} | ||
|
||
/** | ||
* @psalm-suppress MixedMethodCall | ||
*/ | ||
private function buildCallable(string $key, mixed $source): callable | ||
{ | ||
return match (true) { | ||
is_callable($source) => $source, | ||
$this->isClassName($source) => $this->buildCallable($key, new $source()), | ||
default => throw new RuntimeException("Config key \"{$key}\" should contain a callable"), | ||
}; | ||
} | ||
|
||
public function getThreadDetector(): ?ThreadDetectorInterface | ||
{ | ||
$key = 'threadDetector'; | ||
/** @var mixed $threadDetector */ | ||
$threadDetector = $this->data[$key] ?? null; | ||
|
||
return isset($threadDetector) | ||
? $this->buildObject($key, $threadDetector, ThreadDetectorInterface::class) | ||
: null; | ||
} | ||
|
||
/** | ||
* @return list<LifecycleHookInterface> | ||
*/ | ||
public function getLifecycleHooks(): array | ||
{ | ||
$key = 'lifecycleHooks'; | ||
$hooks = []; | ||
/** @psalm-var mixed $hookSource */ | ||
foreach ($this->getArrayFromData($key) as $index => $hookSource) { | ||
if (!is_int($index)) { | ||
throw new RuntimeException( | ||
"Config key \"{$key}\" should contain an array with integer keys only", | ||
); | ||
} | ||
$hooks[] = $this->buildObject( | ||
"{$key}/{$index}", | ||
$hookSource, | ||
LifecycleHookInterface::class, | ||
); | ||
} | ||
|
||
return $hooks; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Qameta\Allure\PHPUnit\Internal; | ||
|
||
use Qameta\Allure\Hook\LifecycleHookInterface; | ||
use Qameta\Allure\PHPUnit\Setup\ThreadDetectorInterface; | ||
use Qameta\Allure\Setup\LinkTemplateInterface; | ||
|
||
interface ConfigInterface | ||
{ | ||
|
||
public function getOutputDirectory(): ?string; | ||
|
||
/** | ||
* @return array<string, LinkTemplateInterface> | ||
*/ | ||
public function getLinkTemplates(): array; | ||
|
||
public function getSetupHook(): ?callable; | ||
|
||
public function getThreadDetector(): ?ThreadDetectorInterface; | ||
|
||
/** | ||
* @return list<LifecycleHookInterface> | ||
*/ | ||
public function getLifecycleHooks(): array; | ||
} |
Oops, something went wrong.