Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Behat / Gherkin / ServiceContainer / GherkinExtension.php
1 <?php
2
3 /*
4  * This file is part of the Behat.
5  * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 namespace Behat\Behat\Gherkin\ServiceContainer;
12
13 use Behat\Testwork\Cli\ServiceContainer\CliExtension;
14 use Behat\Testwork\Filesystem\ServiceContainer\FilesystemExtension;
15 use Behat\Testwork\ServiceContainer\Exception\ExtensionException;
16 use Behat\Testwork\ServiceContainer\Extension;
17 use Behat\Testwork\ServiceContainer\ExtensionManager;
18 use Behat\Testwork\ServiceContainer\ServiceProcessor;
19 use Behat\Testwork\Specification\ServiceContainer\SpecificationExtension;
20 use Behat\Testwork\Suite\ServiceContainer\SuiteExtension;
21 use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension;
22 use ReflectionClass;
23 use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
24 use Symfony\Component\DependencyInjection\ContainerBuilder;
25 use Symfony\Component\DependencyInjection\Definition;
26 use Symfony\Component\DependencyInjection\Reference;
27
28 /**
29  * Extends Behat with gherkin suites and features.
30  *
31  * @author Konstantin Kudryashov <ever.zet@gmail.com>
32  */
33 final class GherkinExtension implements Extension
34 {
35     /*
36      * Available services
37      */
38     const MANAGER_ID = 'gherkin';
39     const KEYWORDS_DUMPER_ID = 'gherkin.keywords_dumper';
40     const KEYWORDS_ID = 'gherkin.keywords';
41
42     /*
43      * Available extension points
44      */
45     const LOADER_TAG = 'gherkin.loader';
46
47     /**
48      * @var ServiceProcessor
49      */
50     private $processor;
51
52     /**
53      * Initializes extension.
54      *
55      * @param null|ServiceProcessor $processor
56      */
57     public function __construct(ServiceProcessor $processor = null)
58     {
59         $this->processor = $processor ? : new ServiceProcessor();
60     }
61
62     /**
63      * {@inheritdoc}
64      */
65     public function getConfigKey()
66     {
67         return 'gherkin';
68     }
69
70     /**
71      * {@inheritdoc}
72      */
73     public function initialize(ExtensionManager $extensionManager)
74     {
75     }
76
77     /**
78      * {@inheritdoc}
79      */
80     public function configure(ArrayNodeDefinition $builder)
81     {
82         $builder
83             ->addDefaultsIfNotSet()
84             ->children()
85                 ->scalarNode('cache')
86                     ->info('Sets the gherkin parser cache folder')
87                     ->defaultValue(
88                         is_writable(sys_get_temp_dir())
89                             ? sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'behat_gherkin_cache'
90                             : null
91                     )
92                 ->end()
93                 ->arrayNode('filters')
94                     ->info('Sets the gherkin filters (overridable by CLI options)')
95                     ->performNoDeepMerging()
96                     ->defaultValue(array())
97                     ->useAttributeAsKey('name')
98                     ->prototype('scalar')->end()
99                 ->end()
100             ->end()
101         ;
102     }
103
104     /**
105      * {@inheritdoc}
106      */
107     public function load(ContainerBuilder $container, array $config)
108     {
109         $this->loadParameters($container);
110         $this->loadGherkin($container);
111         $this->loadKeywords($container);
112         $this->loadParser($container);
113         $this->loadDefaultLoaders($container, $config['cache']);
114         $this->loadProfileFilters($container, $config['filters']);
115         $this->loadSyntaxController($container);
116         $this->loadFilterController($container);
117         $this->loadSuiteWithPathsSetup($container);
118         $this->loadFilesystemFeatureLocator($container);
119         $this->loadFilesystemScenariosListLocator($container);
120         $this->loadFilesystemRerunScenariosListLocator($container);
121     }
122
123     /**
124      * {@inheritdoc}
125      */
126     public function process(ContainerBuilder $container)
127     {
128         $this->processLoaders($container);
129     }
130
131     /**
132      * Loads default container parameters.
133      *
134      * @param ContainerBuilder $container
135      */
136     private function loadParameters(ContainerBuilder $container)
137     {
138         $container->setParameter('gherkin.paths.lib', $this->getLibPath());
139         $container->setParameter('gherkin.paths.i18n', '%gherkin.paths.lib%/i18n.php');
140         $container->setParameter(
141             'suite.generic.default_settings',
142             array(
143                 'paths'    => array('%paths.base%/features'),
144                 'contexts' => array('FeatureContext')
145             )
146         );
147     }
148
149     /**
150      * Returns gherkin library path.
151      *
152      * @return string
153      */
154     private function getLibPath()
155     {
156         $reflection = new ReflectionClass('Behat\Gherkin\Gherkin');
157         $libPath = rtrim(dirname($reflection->getFilename()) . '/../../../', DIRECTORY_SEPARATOR);
158
159         return $libPath;
160     }
161
162     /**
163      * Loads gherkin service.
164      *
165      * @param ContainerBuilder $container
166      */
167     private function loadGherkin(ContainerBuilder $container)
168     {
169         $definition = new Definition('Behat\Gherkin\Gherkin');
170         $container->setDefinition(self::MANAGER_ID, $definition);
171     }
172
173     /**
174      * Loads keyword services.
175      *
176      * @param ContainerBuilder $container
177      */
178     private function loadKeywords(ContainerBuilder $container)
179     {
180         $definition = new Definition('Behat\Gherkin\Keywords\CachedArrayKeywords', array(
181             '%gherkin.paths.i18n%'
182         ));
183         $container->setDefinition(self::KEYWORDS_ID, $definition);
184
185         $definition = new Definition('Behat\Gherkin\Keywords\KeywordsDumper', array(
186             new Reference(self::KEYWORDS_ID)
187         ));
188         $container->setDefinition(self::KEYWORDS_DUMPER_ID, $definition);
189     }
190
191     /**
192      * Loads gherkin parser.
193      *
194      * @param ContainerBuilder $container
195      */
196     private function loadParser(ContainerBuilder $container)
197     {
198         $definition = new Definition('Behat\Gherkin\Parser', array(
199             new Reference('gherkin.lexer')
200         ));
201         $container->setDefinition('gherkin.parser', $definition);
202
203         $definition = new Definition('Behat\Gherkin\Lexer', array(
204             new Reference('gherkin.keywords')
205         ));
206         $container->setDefinition('gherkin.lexer', $definition);
207     }
208
209     /**
210      * Loads gherkin loaders.
211      *
212      * @param ContainerBuilder $container
213      * @param string           $cachePath
214      */
215     private function loadDefaultLoaders(ContainerBuilder $container, $cachePath)
216     {
217         $definition = new Definition('Behat\Gherkin\Loader\GherkinFileLoader', array(
218             new Reference('gherkin.parser')
219         ));
220
221         if ($cachePath) {
222             $cacheDefinition = new Definition('Behat\Gherkin\Cache\FileCache', array($cachePath));
223         } else {
224             $cacheDefinition = new Definition('Behat\Gherkin\Cache\MemoryCache');
225         }
226
227         $definition->addMethodCall('setCache', array($cacheDefinition));
228         $definition->addMethodCall('setBasePath', array('%paths.base%'));
229         $definition->addTag(self::LOADER_TAG, array('priority' => 50));
230         $container->setDefinition('gherkin.loader.gherkin_file', $definition);
231     }
232
233     /**
234      * Loads profile-level gherkin filters.
235      *
236      * @param ContainerBuilder $container
237      * @param array            $filters
238      */
239     private function loadProfileFilters(ContainerBuilder $container, array $filters)
240     {
241         $gherkin = $container->getDefinition(self::MANAGER_ID);
242         foreach ($filters as $type => $filterString) {
243             $filter = $this->createFilterDefinition($type, $filterString);
244             $gherkin->addMethodCall('addFilter', array($filter));
245         }
246     }
247
248     /**
249      * Loads syntax controller.
250      *
251      * @param ContainerBuilder $container
252      */
253     private function loadSyntaxController(ContainerBuilder $container)
254     {
255         $definition = new Definition('Behat\Behat\Gherkin\Cli\SyntaxController', array(
256             new Reference(self::KEYWORDS_DUMPER_ID),
257             new Reference(TranslatorExtension::TRANSLATOR_ID)
258         ));
259         $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 600));
260         $container->setDefinition(CliExtension::CONTROLLER_TAG . '.gherkin_syntax', $definition);
261     }
262
263     /**
264      * Loads filter controller.
265      *
266      * @param ContainerBuilder $container
267      */
268     private function loadFilterController(ContainerBuilder $container)
269     {
270         $definition = new Definition('Behat\Behat\Gherkin\Cli\FilterController', array(
271             new Reference(self::MANAGER_ID)
272         ));
273         $definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 700));
274         $container->setDefinition(CliExtension::CONTROLLER_TAG . '.gherkin_filters', $definition);
275     }
276
277     /**
278      * Loads suite with paths setup.
279      *
280      * @param ContainerBuilder $container
281      */
282     private function loadSuiteWithPathsSetup(ContainerBuilder $container)
283     {
284         $definition = new Definition('Behat\Behat\Gherkin\Suite\Setup\SuiteWithPathsSetup', array(
285             '%paths.base%',
286             new Reference(FilesystemExtension::LOGGER_ID)
287         ));
288         $definition->addTag(SuiteExtension::SETUP_TAG, array('priority' => 50));
289         $container->setDefinition(SuiteExtension::SETUP_TAG . '.suite_with_paths', $definition);
290     }
291
292     /**
293      * Loads filesystem feature locator.
294      *
295      * @param ContainerBuilder $container
296      */
297     private function loadFilesystemFeatureLocator(ContainerBuilder $container)
298     {
299         $definition = new Definition('Behat\Behat\Gherkin\Specification\Locator\FilesystemFeatureLocator', array(
300             new Reference(self::MANAGER_ID),
301             '%paths.base%'
302         ));
303         $definition->addTag(SpecificationExtension::LOCATOR_TAG, array('priority' => 60));
304         $container->setDefinition(SpecificationExtension::LOCATOR_TAG . '.filesystem_feature', $definition);
305     }
306
307     /**
308      * Loads filesystem scenarios list locator.
309      *
310      * @param ContainerBuilder $container
311      */
312     private function loadFilesystemScenariosListLocator(ContainerBuilder $container)
313     {
314         $definition = new Definition('Behat\Behat\Gherkin\Specification\Locator\FilesystemScenariosListLocator', array(
315             new Reference(self::MANAGER_ID)
316         ));
317         $definition->addTag(SpecificationExtension::LOCATOR_TAG, array('priority' => 50));
318         $container->setDefinition(SpecificationExtension::LOCATOR_TAG . '.filesystem_scenarios_list', $definition);
319     }
320
321     /**
322      * Loads filesystem rerun scenarios list locator.
323      *
324      * @param ContainerBuilder $container
325      */
326     private function loadFilesystemRerunScenariosListLocator(ContainerBuilder $container)
327     {
328         $definition = new Definition('Behat\Behat\Gherkin\Specification\Locator\FilesystemRerunScenariosListLocator', array(
329             new Reference(self::MANAGER_ID)
330         ));
331         $definition->addTag(SpecificationExtension::LOCATOR_TAG, array('priority' => 50));
332         $container->setDefinition(SpecificationExtension::LOCATOR_TAG . '.filesystem_rerun_scenarios_list', $definition);
333     }
334
335     /**
336      * Processes all available gherkin loaders.
337      *
338      * @param ContainerBuilder $container
339      */
340     private function processLoaders(ContainerBuilder $container)
341     {
342         $references = $this->processor->findAndSortTaggedServices($container, self::LOADER_TAG);
343         $definition = $container->getDefinition(self::MANAGER_ID);
344
345         foreach ($references as $reference) {
346             $definition->addMethodCall('addLoader', array($reference));
347         }
348     }
349
350     /**
351      * Creates filter definition of provided type.
352      *
353      * @param string $type
354      * @param string $filterString
355      *
356      * @return Definition
357      *
358      * @throws ExtensionException If filter type is not recognised
359      */
360     private function createFilterDefinition($type, $filterString)
361     {
362         if ('role' === $type) {
363             return new Definition('Behat\Gherkin\Filter\RoleFilter', array($filterString));
364         }
365
366         if ('name' === $type) {
367             return new Definition('Behat\Gherkin\Filter\NameFilter', array($filterString));
368         }
369
370         if ('tags' === $type) {
371             return new Definition('Behat\Gherkin\Filter\TagFilter', array($filterString));
372         }
373
374         if ('narrative' === $type) {
375             return new Definition('Behat\Gherkin\Filter\NarrativeFilter', array($filterString));
376         }
377
378         throw new ExtensionException(sprintf(
379             '`%s` filter is not supported by the `filters` option of gherkin extension. Supported types are `%s`.',
380             $type,
381             implode('`, `', array('narrative', 'role', 'name', 'tags'))
382         ), 'gherkin');
383     }
384 }