4 * This file is part of the Behat.
5 * (c) Konstantin Kudryashov <ever.zet@gmail.com>
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
11 namespace Behat\Behat\Context\ServiceContainer;
13 use Behat\Behat\Definition\ServiceContainer\DefinitionExtension;
14 use Behat\Behat\Snippet\ServiceContainer\SnippetExtension;
15 use Behat\Testwork\Argument\ServiceContainer\ArgumentExtension;
16 use Behat\Testwork\Autoloader\ServiceContainer\AutoloaderExtension;
17 use Behat\Testwork\Cli\ServiceContainer\CliExtension;
18 use Behat\Testwork\Environment\ServiceContainer\EnvironmentExtension;
19 use Behat\Testwork\Filesystem\ServiceContainer\FilesystemExtension;
20 use Behat\Testwork\ServiceContainer\Extension;
21 use Behat\Testwork\ServiceContainer\ExtensionManager;
22 use Behat\Testwork\ServiceContainer\ServiceProcessor;
23 use Behat\Testwork\Suite\ServiceContainer\SuiteExtension;
24 use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
25 use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
26 use Symfony\Component\DependencyInjection\ContainerBuilder;
27 use Symfony\Component\DependencyInjection\Definition;
28 use Symfony\Component\DependencyInjection\Reference;
31 * Behat context extension.
33 * Extends Behat with context services.
35 * @author Konstantin Kudryashov <ever.zet@gmail.com>
37 final class ContextExtension implements Extension
42 const FACTORY_ID = 'context.factory';
43 const CONTEXT_SNIPPET_GENERATOR_ID = 'snippet.generator.context';
44 const AGGREGATE_RESOLVER_FACTORY_ID = 'context.argument.aggregate_resolver_factory';
47 * Available extension points
49 const CLASS_RESOLVER_TAG = 'context.class_resolver';
50 const ARGUMENT_RESOLVER_TAG = 'context.argument_resolver';
51 const INITIALIZER_TAG = 'context.initializer';
52 const READER_TAG = 'context.reader';
53 const ANNOTATION_READER_TAG = 'context.annotation_reader';
54 const CLASS_GENERATOR_TAG = 'context.class_generator';
55 const SUITE_SCOPED_RESOLVER_FACTORY_TAG = 'context.argument.suite_resolver_factory';
58 * @var ServiceProcessor
63 * Initializes compiler pass.
65 * @param null|ServiceProcessor $processor
67 public function __construct(ServiceProcessor $processor = null)
69 $this->processor = $processor ? : new ServiceProcessor();
75 public function getConfigKey()
83 public function initialize(ExtensionManager $extensionManager)
90 public function configure(ArrayNodeDefinition $builder)
97 public function load(ContainerBuilder $container, array $config)
99 $this->loadFactory($container);
100 $this->loadArgumentResolverFactory($container);
101 $this->loadEnvironmentHandler($container);
102 $this->loadEnvironmentReader($container);
103 $this->loadSuiteSetup($container);
104 $this->loadSnippetAppender($container);
105 $this->loadSnippetGenerators($container);
106 $this->loadSnippetsController($container);
107 $this->loadDefaultClassGenerators($container);
108 $this->loadDefaultContextReaders($container);
114 public function process(ContainerBuilder $container)
116 $this->processClassResolvers($container);
117 $this->processArgumentResolverFactories($container);
118 $this->processArgumentResolvers($container);
119 $this->processContextInitializers($container);
120 $this->processContextReaders($container);
121 $this->processClassGenerators($container);
122 $this->processAnnotationReaders($container);
126 * Loads context factory.
128 * @param ContainerBuilder $container
130 private function loadFactory(ContainerBuilder $container)
132 $definition = new Definition('Behat\Behat\Context\ContextFactory', array(
133 new Reference(ArgumentExtension::CONSTRUCTOR_ARGUMENT_ORGANISER_ID)
135 $container->setDefinition(self::FACTORY_ID, $definition);
139 * Loads argument resolver factory used in the environment handler.
141 * @param ContainerBuilder $container
143 private function loadArgumentResolverFactory(ContainerBuilder $container)
145 $definition = new Definition('Behat\Behat\Context\Argument\CompositeArgumentResolverFactory');
146 $container->setDefinition(self::AGGREGATE_RESOLVER_FACTORY_ID, $definition);
150 * Loads context environment handlers.
152 * @param ContainerBuilder $container
154 private function loadEnvironmentHandler(ContainerBuilder $container)
156 $definition = new Definition('Behat\Behat\Context\Environment\Handler\ContextEnvironmentHandler', array(
157 new Reference(self::FACTORY_ID),
158 new Reference(self::AGGREGATE_RESOLVER_FACTORY_ID)
160 $definition->addTag(EnvironmentExtension::HANDLER_TAG, array('priority' => 50));
161 $container->setDefinition(self::getEnvironmentHandlerId(), $definition);
165 * Loads context environment readers.
167 * @param ContainerBuilder $container
169 private function loadEnvironmentReader(ContainerBuilder $container)
171 $definition = new Definition('Behat\Behat\Context\Environment\Reader\ContextEnvironmentReader');
172 $definition->addTag(EnvironmentExtension::READER_TAG, array('priority' => 50));
173 $container->setDefinition(self::getEnvironmentReaderId(), $definition);
177 * Loads context environment setup.
179 * @param ContainerBuilder $container
181 private function loadSuiteSetup(ContainerBuilder $container)
183 $definition = new Definition('Behat\Behat\Context\Suite\Setup\SuiteWithContextsSetup', array(
184 new Reference(AutoloaderExtension::CLASS_LOADER_ID),
185 new Reference(FilesystemExtension::LOGGER_ID)
187 $definition->addTag(SuiteExtension::SETUP_TAG, array('priority' => 20));
188 $container->setDefinition(self::getSuiteSetupId(), $definition);
192 * Loads context snippet appender.
194 * @param ContainerBuilder $container
196 private function loadSnippetAppender(ContainerBuilder $container)
198 $definition = new Definition('Behat\Behat\Context\Snippet\Appender\ContextSnippetAppender', array(
199 new Reference(FilesystemExtension::LOGGER_ID)
201 $definition->addTag(SnippetExtension::APPENDER_TAG, array('priority' => 50));
202 $container->setDefinition(SnippetExtension::APPENDER_TAG . '.context', $definition);
206 * Loads context snippet generators.
208 * @param ContainerBuilder $container
210 private function loadSnippetGenerators(ContainerBuilder $container)
212 $definition = new Definition('Behat\Behat\Context\Snippet\Generator\ContextSnippetGenerator', array(
213 new Reference(DefinitionExtension::PATTERN_TRANSFORMER_ID)
215 $definition->addTag(SnippetExtension::GENERATOR_TAG, array('priority' => 50));
216 $container->setDefinition(self::CONTEXT_SNIPPET_GENERATOR_ID, $definition);
220 * @param ContainerBuilder $container
222 protected function loadSnippetsController(ContainerBuilder $container)
224 $definition = new Definition('Behat\Behat\Context\Cli\ContextSnippetsController', array(
225 new Reference(self::CONTEXT_SNIPPET_GENERATOR_ID),
226 new Reference(TranslatorExtension::TRANSLATOR_ID)
228 $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 410));
229 $container->setDefinition(CliExtension::CONTROLLER_TAG . '.context_snippets', $definition);
233 * Loads default context class generators.
235 * @param ContainerBuilder $container
237 private function loadDefaultClassGenerators(ContainerBuilder $container)
239 $definition = new Definition('Behat\Behat\Context\ContextClass\SimpleClassGenerator');
240 $definition->addTag(self::CLASS_GENERATOR_TAG, array('priority' => 50));
241 $container->setDefinition(self::CLASS_GENERATOR_TAG . '.simple', $definition);
245 * Loads default context readers.
247 * @param ContainerBuilder $container
249 private function loadDefaultContextReaders(ContainerBuilder $container)
251 $definition = new Definition('Behat\Behat\Context\Reader\AnnotatedContextReader');
252 $container->setDefinition(self::getAnnotatedContextReaderId(), $definition);
254 $definition = new Definition('Behat\Behat\Context\Reader\ContextReaderCachedPerContext', array(
255 new Reference(self::getAnnotatedContextReaderId())
257 $definition->addTag(self::READER_TAG, array('priority' => 50));
258 $container->setDefinition(self::getAnnotatedContextReaderId() . '.cached', $definition);
260 $definition = new Definition('Behat\Behat\Context\Reader\TranslatableContextReader', array(
261 new Reference(TranslatorExtension::TRANSLATOR_ID)
263 $container->setDefinition(self::READER_TAG . '.translatable', $definition);
265 $definition = new Definition('Behat\Behat\Context\Reader\ContextReaderCachedPerSuite', array(
266 new Reference(self::READER_TAG . '.translatable')
268 $definition->addTag(self::READER_TAG, array('priority' => 50));
269 $container->setDefinition(self::READER_TAG . '.translatable.cached', $definition);
273 * Processes all class resolvers.
275 * @param ContainerBuilder $container
277 private function processClassResolvers(ContainerBuilder $container)
279 $references = $this->processor->findAndSortTaggedServices($container, self::CLASS_RESOLVER_TAG);
280 $definition = $container->getDefinition(self::getEnvironmentHandlerId());
282 foreach ($references as $reference) {
283 $definition->addMethodCall('registerClassResolver', array($reference));
288 * Processes all argument resolver factories.
290 * @param ContainerBuilder $container
292 private function processArgumentResolverFactories($container)
294 $references = $this->processor->findAndSortTaggedServices($container, self::SUITE_SCOPED_RESOLVER_FACTORY_TAG);
295 $definition = $container->getDefinition(self::AGGREGATE_RESOLVER_FACTORY_ID);
297 foreach ($references as $reference) {
298 $definition->addMethodCall('registerFactory', array($reference));
303 * Processes all argument resolvers.
305 * @param ContainerBuilder $container
307 private function processArgumentResolvers(ContainerBuilder $container)
309 $references = $this->processor->findAndSortTaggedServices($container, self::ARGUMENT_RESOLVER_TAG);
310 $definition = $container->getDefinition(self::FACTORY_ID);
312 foreach ($references as $reference) {
313 $definition->addMethodCall('registerArgumentResolver', array($reference));
318 * Processes all context initializers.
320 * @param ContainerBuilder $container
322 private function processContextInitializers(ContainerBuilder $container)
324 $references = $this->processor->findAndSortTaggedServices($container, self::INITIALIZER_TAG);
325 $definition = $container->getDefinition(self::FACTORY_ID);
327 foreach ($references as $reference) {
328 $definition->addMethodCall('registerContextInitializer', array($reference));
333 * Processes all context readers.
335 * @param ContainerBuilder $container
337 private function processContextReaders(ContainerBuilder $container)
339 $references = $this->processor->findAndSortTaggedServices($container, self::READER_TAG);
340 $definition = $container->getDefinition(self::getEnvironmentReaderId());
342 foreach ($references as $reference) {
343 $definition->addMethodCall('registerContextReader', array($reference));
348 * Processes all class generators.
350 * @param ContainerBuilder $container
352 private function processClassGenerators(ContainerBuilder $container)
354 $references = $this->processor->findAndSortTaggedServices($container, self::CLASS_GENERATOR_TAG);
355 $definition = $container->getDefinition(self::getSuiteSetupId());
357 foreach ($references as $reference) {
358 $definition->addMethodCall('registerClassGenerator', array($reference));
363 * Processes all annotation readers.
365 * @param ContainerBuilder $container
367 private function processAnnotationReaders(ContainerBuilder $container)
369 $references = $this->processor->findAndSortTaggedServices($container, self::ANNOTATION_READER_TAG);
370 $definition = $container->getDefinition(self::getAnnotatedContextReaderId());
372 foreach ($references as $reference) {
373 $definition->addMethodCall('registerAnnotationReader', array($reference));
378 * Returns context environment handler service id.
382 private static function getEnvironmentHandlerId()
384 return EnvironmentExtension::HANDLER_TAG . '.context';
388 * Returns context environment reader id.
392 private static function getEnvironmentReaderId()
394 return EnvironmentExtension::READER_TAG . '.context';
398 * Returns context suite setup id.
402 private static function getSuiteSetupId()
404 return SuiteExtension::SETUP_TAG . '.suite_with_contexts';
408 * Returns annotated context reader id.
412 private static function getAnnotatedContextReaderId()
414 return self::READER_TAG . '.annotated';