From b7c3f39647a2c3cbb83465d42f84d9e7636f3f18 Mon Sep 17 00:00:00 2001
From: diosmosis <benakamoorthi@fastmail.fm>
Date: Sun, 15 Jun 2014 15:40:05 -0700
Subject: [PATCH] When executing tests, check for non-core plugin that should
 be loaded by looking at test case class & current backtrace. (Removing need
 for enable_load_standalone_plugins_during_tests config option).

---
 core/Plugin.php                               | 27 +++++++++++++++----
 tests/PHPUnit/Fixture.php                     | 23 ++++++++++++++--
 tests/PHPUnit/IntegrationTestCase.php         |  2 ++
 tests/PHPUnit/TestingEnvironment.php          |  9 +++++++
 .../support/test-environment.js               |  8 ++++++
 5 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/core/Plugin.php b/core/Plugin.php
index aeb687398e..2ddd07aa26 100644
--- a/core/Plugin.php
+++ b/core/Plugin.php
@@ -353,12 +353,29 @@ class Plugin
     {
         foreach ($backtrace as $tracepoint) {
             // try and discern the plugin name
-            if (isset($tracepoint['class'])
-                && preg_match("/Piwik\\\\Plugins\\\\([a-zA-Z_0-9]+)\\\\/", $tracepoint['class'], $matches)
-            ) {
-                return $matches[1];
+            if (isset($tracepoint['class'])) {
+                $className = self::getPluginNameFromNamespace($tracepoint['class']);
+                if ($className) {
+                    return $className;
+                }
             }
         }
         return false;
     }
-}
+
+    /**
+     * Extracts the plugin name from a namespace name or a fully qualified class name. Returns `false`
+     * if we can't find one.
+     *
+     * @param string $namespaceOrClassName The namespace or class string.
+     * @return string|false
+     */
+    public static function getPluginNameFromNamespace($namespaceOrClassName)
+    {
+        if (preg_match("/Piwik\\\\Plugins\\\\([a-zA-Z_0-9]+)\\\\/", $namespaceOrClassName, $matches)) {
+            return $matches[1];
+        } else {
+            return false;
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/PHPUnit/Fixture.php b/tests/PHPUnit/Fixture.php
index 367a744bc9..f651dd1d75 100644
--- a/tests/PHPUnit/Fixture.php
+++ b/tests/PHPUnit/Fixture.php
@@ -67,6 +67,8 @@ class Fixture extends PHPUnit_Framework_Assert
     public $resetPersistedFixture = false;
     public $printToScreen = false;
 
+    public $testCaseClass = false;
+
     public $testEnvironment = null;
 
     /**
@@ -173,7 +175,7 @@ class Fixture extends PHPUnit_Framework_Assert
 
         Cache::deleteTrackerCache();
 
-        static::loadAllPlugins();
+        static::loadAllPlugins($this->getTestEnvironment(), $this->testCaseClass);
 
         $_GET = $_REQUEST = array();
         $_SERVER['HTTP_REFERER'] = '';
@@ -265,12 +267,29 @@ class Fixture extends PHPUnit_Framework_Assert
         Translate::unloadEnglishTranslation();
     }
 
-    public static function loadAllPlugins()
+    public static function loadAllPlugins($testEnvironment = null, $testCaseClass = false)
     {
         DbHelper::createTables();
         $pluginsManager = \Piwik\Plugin\Manager::getInstance();
 
         $plugins = $pluginsManager->getPluginsToLoadDuringTests();
+
+        // make sure the plugin that executed this method is included in the plugins to load
+        $extraPlugins = array(
+            \Piwik\Plugin::getPluginNameFromBacktrace(debug_backtrace()),
+            \Piwik\Plugin::getPluginNameFromNamespace($testCaseClass)
+        );
+        foreach ($extraPlugins as $pluginName) {
+            if (empty($pluginName)) {
+                continue;
+            }
+
+            $plugins[] = $pluginName;
+            if ($testEnvironment) {
+                $testEnvironment->pluginsToLoad = array_merge($testEnvironment->pluginsToLoad ?: array(), array($pluginName));
+            }
+        }
+
         Log::info("Plugins to load during tests: " . implode(', ', $plugins));
 
         $pluginsManager->loadPlugins($plugins);
diff --git a/tests/PHPUnit/IntegrationTestCase.php b/tests/PHPUnit/IntegrationTestCase.php
index f51bc3e35f..8ca26efcff 100755
--- a/tests/PHPUnit/IntegrationTestCase.php
+++ b/tests/PHPUnit/IntegrationTestCase.php
@@ -78,6 +78,8 @@ abstract class IntegrationTestCase extends PHPUnit_Framework_TestCase
             $fixture = static::$fixture;
         }
 
+        $fixture->testCaseClass = get_called_class();
+
         try {
             $fixture->performSetUp();
         } catch (Exception $e) {
diff --git a/tests/PHPUnit/TestingEnvironment.php b/tests/PHPUnit/TestingEnvironment.php
index 28e1a70d60..c9ea3a2be8 100644
--- a/tests/PHPUnit/TestingEnvironment.php
+++ b/tests/PHPUnit/TestingEnvironment.php
@@ -62,6 +62,11 @@ class Piwik_TestingEnvironment
         $this->behaviorOverrideProperties[$key] = $value;
     }
 
+    public function __isset($name)
+    {
+        return isset($this->behaviorOverrideProperties[$name]);
+    }
+
     public function save()
     {
         $overridePath = PIWIK_INCLUDE_PATH . '/tmp/testingPathOverride.json';
@@ -124,6 +129,10 @@ class Piwik_TestingEnvironment
 
                 $manager = \Piwik\Plugin\Manager::getInstance();
                 $pluginsToLoad = $manager->getPluginsToLoadDuringTests();
+                if (!empty($testingEnvironment->pluginsToLoad)) {
+                    $pluginsToLoad = array_unique(array_merge($pluginsToLoad, $testingEnvironment->pluginsToLoad));
+                }
+
                 $config->Plugins = array('Plugins' => $pluginsToLoad);
 
                 $trackerPluginsToLoad = array_filter($pluginsToLoad, function ($plugin) use ($manager) {
diff --git a/tests/lib/screenshot-testing/support/test-environment.js b/tests/lib/screenshot-testing/support/test-environment.js
index e7a0f1f44e..375408e562 100644
--- a/tests/lib/screenshot-testing/support/test-environment.js
+++ b/tests/lib/screenshot-testing/support/test-environment.js
@@ -118,6 +118,13 @@ TestingEnvironment.prototype.executeConsoleCommand = function (command, args, ca
     child.on("exit", callback);
 };
 
+TestingEnvironment.prototype.addPluginOnCmdLineToTestEnv = function () {
+    if (options.plugin) {
+        this.pluginsToLoad = [options.plugin];
+        this.save();
+    }
+};
+
 var droppedOnce = false;
 TestingEnvironment.prototype.setupFixture = function (fixtureClass, done) {
     console.log("    Setting up fixture " + fixtureClass + "...");
@@ -140,6 +147,7 @@ TestingEnvironment.prototype.setupFixture = function (fixtureClass, done) {
     var self = this;
     this.executeConsoleCommand('tests:setup-fixture', args, function (code) {
         self.reload();
+        self.addPluginOnCmdLineToTestEnv();
 
         console.log();
 
-- 
GitLab