<?php
declare(strict_types=1);
namespace Laminas\Test\PHPUnit\Constraint;
use Exception;
use Laminas\Test\PHPUnit\Controller\AbstractControllerTestCase;
use PHPUnit\Framework\Constraint\Constraint;
use PHPUnit\Framework\ExpectationFailedException;
use SebastianBergmann\Comparator\ComparisonFailure;
use Throwable;
use function get_class;
use function implode;
use function sprintf;
// @codingStandardsIgnoreLine
abstract class LaminasConstraint extends Constraint
{
/** @var AbstractControllerTestCase */
protected $activeTestCase;
public function __construct(AbstractControllerTestCase $activeTestCase)
{
$this->activeTestCase = $activeTestCase;
}
final public function getTestCase(): AbstractControllerTestCase
{
return $this->activeTestCase;
}
/**
* @param mixed $other
* @param string $description
* @psalm-return never
*/
final public function fail($other, $description, ?ComparisonFailure $comparisonFailure = null): void
{
try {
parent::fail($other, $description, $comparisonFailure);
} catch (ExpectationFailedException $failedException) {
throw new ExpectationFailedException(
$this->createFailureMessage($failedException->getMessage()),
$failedException->getComparisonFailure(),
);
}
}
final public function getControllerFullClassName(): string
{
$routeMatch = $this->activeTestCase->getApplication()->getMvcEvent()->getRouteMatch();
$controllerIdentifier = $routeMatch->getParam('controller');
$controllerManager = $this->activeTestCase->getApplicationServiceLocator()->get('ControllerManager');
return get_class($controllerManager->get($controllerIdentifier));
}
/**
* Create a failure message.
*
* If traceError is true, appends exception details, if any.
*/
private function createFailureMessage(string $message): string
{
if (! $this->activeTestCase->getTraceError()) {
return $message;
}
$exception = $this->getTestCase()->getApplication()->getMvcEvent()->getParam('exception');
if (! $exception instanceof Throwable && ! $exception instanceof Exception) {
return $message;
}
$messages = [];
do {
$messages[] = sprintf(
"Exception '%s' with message '%s' in %s:%d",
get_class($exception),
$exception->getMessage(),
$exception->getFile(),
$exception->getLine()
);
} while ($exception = $exception->getPrevious());
return sprintf("%s\n\nExceptions raised:\n%s\n", $message, implode("\n\n", $messages));
}
}