doyolabs /
phpspec-code-coverage
| 1 | <?php |
||
| 2 | |||
| 3 | /* |
||
| 4 | * This file is part of PhpSpec, A php toolset to drive emergent |
||
| 5 | * design by specification. |
||
| 6 | * |
||
| 7 | * (c) Marcello Duarte <[email protected]> |
||
| 8 | * (c) Konstantin Kudryashov <[email protected]> |
||
| 9 | * |
||
| 10 | * For the full copyright and license information, please view the LICENSE |
||
| 11 | * file that was distributed with this source code. |
||
| 12 | */ |
||
| 13 | |||
| 14 | namespace Doyo\PhpSpec\CodeCoverage\Context; |
||
| 15 | |||
| 16 | use PhpSpec\Console\ConsoleIO; |
||
| 17 | use PhpSpec\Console\ContainerAssembler; |
||
| 18 | use PhpSpec\Exception\Configuration\InvalidConfigurationException; |
||
| 19 | use PhpSpec\Matcher\Matcher; |
||
| 20 | use PhpSpec\ServiceContainer; |
||
| 21 | use Symfony\Component\Console\Application as BaseApplication; |
||
| 22 | use PhpSpec\ServiceContainer\IndexedServiceContainer; |
||
| 23 | use PhpSpec\Extension; |
||
| 24 | use Symfony\Component\Console\Command\Command; |
||
| 25 | use Symfony\Component\Console\Helper\DebugFormatterHelper; |
||
| 26 | use Symfony\Component\Console\Helper\FormatterHelper; |
||
| 27 | use Symfony\Component\Console\Helper\HelperSet; |
||
| 28 | use Symfony\Component\Console\Helper\ProcessHelper; |
||
| 29 | use Symfony\Component\Console\Helper\QuestionHelper; |
||
| 30 | use Symfony\Component\Console\Input\StringInput; |
||
| 31 | use Symfony\Component\Console\Output\StreamOutput; |
||
| 32 | |||
| 33 | /** |
||
| 34 | * The command line application entry point |
||
| 35 | * |
||
| 36 | * @internal |
||
| 37 | */ |
||
| 38 | final class Application extends BaseApplication |
||
| 39 | { |
||
| 40 | /** |
||
| 41 | * @var IndexedServiceContainer |
||
| 42 | */ |
||
| 43 | private $container; |
||
| 44 | |||
| 45 | public function __construct($config) |
||
| 46 | { |
||
| 47 | $container = new IndexedServiceContainer(); |
||
| 48 | $container->set('console.commands.run', new Command()); |
||
| 49 | $container->set('console.input', new StringInput('run --coverage')); |
||
| 50 | $container->set('console.output', new StreamOutput(fopen('php://memory','+w'))); |
||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 51 | $container->set('cli.input', new StringInput('run --coverage')); |
||
| 52 | $container->set('cli.output', new StreamOutput(fopen('php://memory','+w'))); |
||
| 53 | $container->set('console.helper_set', $this->getDefaultHelperSet()); |
||
| 54 | $this->loadConfig($container, $config); |
||
| 55 | |||
| 56 | $assembler = new ContainerAssembler(); |
||
| 57 | $assembler->build($container); |
||
| 58 | $container->set('console.input', new StringInput('run --coverage')); |
||
| 59 | $this->container = $container; |
||
| 60 | } |
||
| 61 | |||
| 62 | /** |
||
| 63 | * Gets the default helper set with the helpers that should always be available. |
||
| 64 | * |
||
| 65 | * @return HelperSet A HelperSet instance |
||
| 66 | */ |
||
| 67 | protected function getDefaultHelperSet() |
||
| 68 | { |
||
| 69 | return new HelperSet([ |
||
| 70 | new FormatterHelper(), |
||
| 71 | new DebugFormatterHelper(), |
||
| 72 | new ProcessHelper(), |
||
| 73 | new QuestionHelper(), |
||
| 74 | ]); |
||
| 75 | } |
||
| 76 | |||
| 77 | /** |
||
| 78 | * @throws \RuntimeException |
||
| 79 | */ |
||
| 80 | protected function loadConfig(IndexedServiceContainer $container, array $config) |
||
| 81 | { |
||
| 82 | $this->populateContainerParameters($container, $config); |
||
| 83 | |||
| 84 | foreach ($config as $key => $val) { |
||
| 85 | if ('extensions' === $key && \is_array($val)) { |
||
| 86 | foreach ($val as $class => $extensionConfig) { |
||
| 87 | $this->loadExtension($container, $class, $extensionConfig ?: []); |
||
| 88 | } |
||
| 89 | } |
||
| 90 | elseif ('matchers' === $key && \is_array($val)) { |
||
| 91 | $this->registerCustomMatchers($container, $val); |
||
| 92 | } |
||
| 93 | } |
||
| 94 | } |
||
| 95 | |||
| 96 | /** |
||
| 97 | * @return IndexedServiceContainer |
||
| 98 | */ |
||
| 99 | public function getContainer(): IndexedServiceContainer |
||
| 100 | { |
||
| 101 | return $this->container; |
||
| 102 | } |
||
| 103 | |||
| 104 | private function registerCustomMatchers(IndexedServiceContainer $container, array $matchersClassnames) |
||
| 105 | { |
||
| 106 | foreach ($matchersClassnames as $class) { |
||
| 107 | $this->ensureIsValidMatcherClass($class); |
||
| 108 | |||
| 109 | $container->define(sprintf('matchers.%s', $class), function () use ($class) { |
||
| 110 | return new $class(); |
||
| 111 | }, ['matchers']); |
||
| 112 | } |
||
| 113 | } |
||
| 114 | |||
| 115 | private function ensureIsValidMatcherClass(string $class) |
||
| 116 | { |
||
| 117 | if (!class_exists($class)) { |
||
| 118 | throw new InvalidConfigurationException(sprintf('Custom matcher %s does not exist.', $class)); |
||
| 119 | } |
||
| 120 | |||
| 121 | if (!is_subclass_of($class, Matcher::class)) { |
||
| 122 | throw new InvalidConfigurationException(sprintf( |
||
| 123 | 'Custom matcher %s must implement %s interface, but it does not.', |
||
| 124 | $class, |
||
| 125 | Matcher::class |
||
| 126 | )); |
||
| 127 | } |
||
| 128 | } |
||
| 129 | |||
| 130 | private function loadExtension(ServiceContainer $container, string $extensionClass, $config) |
||
| 131 | { |
||
| 132 | if (!class_exists($extensionClass)) { |
||
| 133 | throw new InvalidConfigurationException(sprintf('Extension class `%s` does not exist.', $extensionClass)); |
||
| 134 | } |
||
| 135 | |||
| 136 | if (!\is_array($config)) { |
||
| 137 | throw new InvalidConfigurationException('Extension configuration must be an array or null.'); |
||
| 138 | } |
||
| 139 | |||
| 140 | if (!is_a($extensionClass, Extension::class, true)) { |
||
| 141 | throw new InvalidConfigurationException(sprintf('Extension class `%s` must implement Extension interface', $extensionClass)); |
||
| 142 | } |
||
| 143 | |||
| 144 | (new $extensionClass)->load($container, $config); |
||
| 145 | } |
||
| 146 | |||
| 147 | private function populateContainerParameters(IndexedServiceContainer $container, array $config) |
||
| 148 | { |
||
| 149 | foreach ($config as $key => $val) { |
||
| 150 | if ('extensions' !== $key && 'matchers' !== $key) { |
||
| 151 | $container->setParam($key, $val); |
||
| 152 | } |
||
| 153 | } |
||
| 154 | } |
||
| 155 | } |
||
| 156 |