Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Behat / HelperContainer / Call / Filter / ServicesResolver.php
diff --git a/vendor/behat/behat/src/Behat/Behat/HelperContainer/Call/Filter/ServicesResolver.php b/vendor/behat/behat/src/Behat/Behat/HelperContainer/Call/Filter/ServicesResolver.php
new file mode 100644 (file)
index 0000000..0c70fef
--- /dev/null
@@ -0,0 +1,204 @@
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\HelperContainer\Call\Filter;
+
+use Behat\Behat\Definition\Definition;
+use Behat\Behat\HelperContainer\Environment\ServiceContainerEnvironment;
+use Behat\Behat\Definition\Call\DefinitionCall;
+use Behat\Behat\HelperContainer\ArgumentAutowirer;
+use Behat\Behat\HelperContainer\Exception\UnsupportedCallException;
+use Behat\Behat\Transformation\Call\TransformationCall;
+use Behat\Behat\Transformation\Transformation;
+use Behat\Testwork\Call\Call;
+use Behat\Testwork\Call\Filter\CallFilter;
+use Behat\Testwork\Environment\Call\EnvironmentCall;
+use Psr\Container\ContainerExceptionInterface;
+use Psr\Container\ContainerInterface;
+
+/**
+ * Dynamically resolves call arguments using the service container.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ServicesResolver implements CallFilter
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function supportsCall(Call $call)
+    {
+        return ($call instanceof DefinitionCall || $call instanceof TransformationCall)
+            && $call->getEnvironment() instanceof ServiceContainerEnvironment;
+    }
+
+    /**
+     * Filters a call and returns a new one.
+     *
+     * @param Call $call
+     *
+     * @return Call
+     *
+     * @throws UnsupportedCallException
+     * @throws ContainerExceptionInterface
+     */
+    public function filterCall(Call $call)
+    {
+        if ($container = $this->getContainer($call)) {
+            $autowirer = new ArgumentAutowirer($container);
+            $newArguments = $autowirer->autowireArguments($call->getCallee()->getReflection(), $call->getArguments());
+
+            return $this->repackageCallIfNewArguments($call, $newArguments);
+        }
+
+        return $call;
+    }
+
+    /**
+     * Gets container from the call.
+     *
+     * @param Call $call
+     *
+     * @return null|ContainerInterface
+     *
+     * @throws UnsupportedCallException if given call is not EnvironmentCall or environment is not ServiceContainerEnvironment
+     */
+    private function getContainer(Call $call)
+    {
+        if (!$call instanceof EnvironmentCall) {
+            throw new UnsupportedCallException(sprintf(
+                'ServicesResolver can not filter `%s` call.',
+                get_class($call)
+            ), $call);
+        }
+
+        $environment = $call->getEnvironment();
+
+        if (!$environment instanceof ServiceContainerEnvironment) {
+            throw new UnsupportedCallException(sprintf(
+                'ServicesResolver can not filter `%s` call.',
+                get_class($call)
+            ), $call);
+        }
+
+        return $environment->getServiceContainer();
+    }
+
+    /**
+     * Repackages old calls with new arguments, but only if two differ.
+     *
+     * @param Call $call
+     * @param array $arguments
+     *
+     * @return Call
+     *
+     * @throws UnsupportedCallException if given call is not DefinitionCall or TransformationCall
+     */
+    private function repackageCallIfNewArguments(Call $call, array $arguments)
+    {
+        if ($arguments === $call->getArguments()) {
+            return $call;
+        }
+
+        return $this->repackageCallWithNewArguments($call, $arguments);
+    }
+
+    /**
+     * Repackages old calls with new arguments.
+     *
+     * @param Call  $call
+     * @param array $newArguments
+     *
+     * @return DefinitionCall|TransformationCall
+     *
+     * @throws UnsupportedCallException
+     */
+    private function repackageCallWithNewArguments(Call $call, array $newArguments)
+    {
+        if ($call instanceof DefinitionCall) {
+            return $this->repackageDefinitionCall($call, $newArguments);
+        }
+
+        if ($call instanceof TransformationCall) {
+            return $this->repackageTransformationCall($call, $newArguments);
+        }
+
+        throw new UnsupportedCallException(
+            sprintf(
+                'ServicesResolver can not filter `%s` call.',
+                get_class($call)
+            ), $call
+        );
+    }
+
+    /**
+     * Repackages definition call with new arguments.
+     *
+     * @param DefinitionCall $call
+     * @param array $newArguments
+     *
+     * @return DefinitionCall
+     *
+     * @throws UnsupportedCallException
+     */
+    private function repackageDefinitionCall(DefinitionCall $call, array $newArguments)
+    {
+        $definition = $call->getCallee();
+
+        if (!$definition instanceof Definition) {
+            throw new UnsupportedCallException(
+                sprintf(
+                    'Something is wrong in callee associated with `%s` call.',
+                    get_class($call)
+                ), $call
+            );
+        }
+
+        return new DefinitionCall(
+            $call->getEnvironment(),
+            $call->getFeature(),
+            $call->getStep(),
+            $definition,
+            $newArguments,
+            $call->getErrorReportingLevel()
+        );
+    }
+
+    /**
+     * Repackages transformation call with new arguments.
+     *
+     * @param TransformationCall $call
+     * @param array $newArguments
+     *
+     * @return TransformationCall
+     *
+     * @throws UnsupportedCallException
+     */
+    private function repackageTransformationCall(TransformationCall $call, array $newArguments)
+    {
+        $transformation = $call->getCallee();
+
+        if (!$transformation instanceof Transformation) {
+            throw new UnsupportedCallException(
+                sprintf(
+                    'Something is wrong in callee associated with `%s` call.',
+                    get_class($call)
+                ), $call
+            );
+        }
+
+        return new TransformationCall(
+            $call->getEnvironment(),
+            $call->getDefinition(),
+            $transformation,
+            $newArguments
+        );
+    }
+}