Security update for permissions_by_term
[yaffs-website] / vendor / drupal / drupal-extension / src / Drupal / DrupalExtension / Context / Environment / Reader / Reader.php
diff --git a/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/Environment/Reader/Reader.php b/vendor/drupal/drupal-extension/src/Drupal/DrupalExtension/Context/Environment/Reader/Reader.php
new file mode 100644 (file)
index 0000000..dace00d
--- /dev/null
@@ -0,0 +1,229 @@
+<?php
+
+namespace Drupal\DrupalExtension\Context\Environment\Reader;
+
+use Behat\Behat\Context\Environment\UninitializedContextEnvironment;
+use Behat\Behat\Context\Environment\ContextEnvironment;
+use Behat\Behat\Context\Reader\ContextReader;
+use Behat\Testwork\Call\Callee;
+use Behat\Testwork\Environment\Environment;
+use Behat\Testwork\Environment\Exception\EnvironmentReadException;
+use Behat\Testwork\Environment\Reader\EnvironmentReader;
+
+use Drupal\DrupalDriverManager;
+use Drupal\Driver\SubDriverFinderInterface;
+
+use RecursiveDirectoryIterator;
+use RecursiveIteratorIterator;
+use RegexIterator;
+
+/**
+ * Read in additional contexts provided by core and contrib.
+ */
+final class Reader implements EnvironmentReader {
+
+  /**
+   * @var ContextReader[]
+   */
+  private $contextReaders = array();
+
+  /**
+   * Drupal driver manager.
+   *
+   * @var \Drupal\DrupalDriverManager
+   */
+  private $drupal;
+
+  /**
+   * Configuration parameters for this suite.
+   */
+  private $parameters;
+
+  /**
+   * Statically cached lists of subcontexts by path.
+   *
+   * @var array
+   */
+  static protected $subContexts;
+
+  /**
+   * Register the Drupal driver manager.
+   */
+  public function __construct(DrupalDriverManager $drupal, array $parameters) {
+    $this->drupal = $drupal;
+    $this->parameters = $parameters;
+  }
+
+  /**
+   * Registers context loader.
+   *
+   * @param ContextReader $contextReader
+   */
+  public function registerContextReader(ContextReader $contextReader) {
+    $this->contextReaders[] = $contextReader;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function supportsEnvironment(Environment $environment) {
+    return $environment instanceof ContextEnvironment;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function readEnvironmentCallees(Environment $environment) {
+
+    if (!$environment instanceof ContextEnvironment) {
+      throw new EnvironmentReadException(sprintf(
+          'ContextEnvironmentReader does not support `%s` environment.',
+          get_class($environment)
+        ), $environment);
+    }
+
+    $callees = array();
+    if (!$environment instanceof UninitializedContextEnvironment) {
+      return $callees;
+    }
+
+    $contextClasses = $this->findSubContextClasses();
+
+    foreach ($contextClasses as $contextClass) {
+      // When executing test scenarios with an examples table the registering of
+      // contexts is handled differently in newer version of Behat. Starting
+      // with Behat 3.2.0 the contexts are already registered, and the callees
+      // are returned by the default reader.
+      // Work around this and provide compatibility with Behat 3.1.0 as well as
+      // 3.2.0 and higher by checking if the class already exists before
+      // registering it and returning the callees.
+      // @see https://github.com/Behat/Behat/issues/758
+      if (!$environment->hasContextClass($contextClass)) {
+        $callees = array_merge(
+          $callees,
+          $this->readContextCallees($environment, $contextClass)
+        );
+
+        // Register context.
+        $environment->registerContextClass($contextClass, array($this->drupal));
+      }
+    }
+
+    return $callees;
+  }
+
+    /**
+     * Reads callees from a specific suite's context.
+     *
+     * @param ContextEnvironment $environment
+     * @param string             $contextClass
+     *
+     * @return Callee[]
+     */
+    private function readContextCallees(ContextEnvironment $environment, $contextClass)
+    {
+        $callees = array();
+        foreach ($this->contextReaders as $loader) {
+            $callees = array_merge(
+                $callees,
+                $loader->readContextCallees($environment, $contextClass)
+            );
+        }
+
+        return $callees;
+    }
+
+  /**
+   * Finds and loads available subcontext classes.
+   */
+  private function findSubContextClasses() {
+    $class_names = array();
+
+    // Initialize any available sub-contexts.
+    if (isset($this->parameters['subcontexts'])) {
+      $paths = array();
+      // Drivers may specify paths to subcontexts.
+      if ($this->parameters['subcontexts']['autoload']) {
+        foreach ($this->drupal->getDrivers() as $name => $driver) {
+          if ($driver instanceof SubDriverFinderInterface) {
+            $paths += $driver->getSubDriverPaths();
+          }
+        }
+      }
+
+      // Additional subcontext locations may be specified manually in behat.yml.
+      if (isset($this->parameters['subcontexts']['paths'])) {
+        $paths = array_merge($paths, $this->parameters['subcontexts']['paths']);
+      }
+
+      // Load each class.
+      foreach ($paths as $path) {
+        if ($subcontexts = $this->findAvailableSubContexts($path)) {
+          $this->loadSubContexts($subcontexts);
+        }
+      }
+
+      // Find all subcontexts, excluding abstract base classes.
+      $classes = get_declared_classes();
+      foreach ($classes as $class) {
+        $reflect = new \ReflectionClass($class);
+        if (!$reflect->isAbstract() && $reflect->implementsInterface('Drupal\DrupalExtension\Context\DrupalSubContextInterface')) {
+          $class_names[] = $class;
+        }
+      }
+
+    }
+
+    return $class_names;
+  }
+
+  /**
+   * Find Sub-contexts matching a given pattern located at the passed path.
+   *
+   * @param string $path
+   *   Absolute path to the directory to search for sub-contexts.
+   * @param string $pattern
+   *   File pattern to match. Defaults to `/^.+\.behat\.inc/i`.
+   *
+   * @return array
+   *   An array of paths.
+   */
+  private function findAvailableSubContexts($path, $pattern = '/^.+\.behat\.inc/i') {
+
+    if (isset(static::$subContexts[$pattern][$path])) {
+      return static::$subContexts[$pattern][$path];
+    }
+
+    static::$subContexts[$pattern][$path] = array();
+
+    $fileIterator = new RegexIterator(
+      new RecursiveIteratorIterator(
+        new RecursiveDirectoryIterator($path)
+      ), $pattern,
+      RegexIterator::MATCH
+    );
+    foreach ($fileIterator as $found) {
+      static::$subContexts[$pattern][$path][$found->getRealPath()] = $found->getFileName();
+    }
+
+    return static::$subContexts[$pattern][$path];
+  }
+
+  /**
+   * Load each subcontext file.
+   *
+   * @param array $subcontexts
+   *   An array of files to include.
+   */
+  private function loadSubContexts($subcontexts) {
+    foreach ($subcontexts as $path => $subcontext) {
+      if (!file_exists($path)) {
+        throw new \RuntimeException(sprintf('Subcontext path %s path does not exist.', $path));
+      }
+
+      // Load file.
+      require_once $path;
+    }
+  }
+
+}