forked from github/pelican
286 lines
11 KiB
Python
286 lines
11 KiB
Python
import os
|
|
from contextlib import contextmanager
|
|
|
|
from pelican.plugins._utils import (
|
|
get_namespace_plugins,
|
|
get_plugin_name,
|
|
load_plugins,
|
|
plugin_enabled,
|
|
)
|
|
from pelican.plugins.signals import signal
|
|
from pelican.tests.dummy_plugins.normal_plugin import normal_plugin
|
|
from pelican.tests.support import unittest
|
|
|
|
|
|
@contextmanager
|
|
def tmp_namespace_path(path):
|
|
"""Context manager for temporarily appending namespace plugin packages
|
|
|
|
path: path containing the `pelican` folder
|
|
|
|
This modifies the `pelican.__path__` and lets the `pelican.plugins`
|
|
namespace package resolve it from that.
|
|
"""
|
|
# This avoids calls to internal `pelican.plugins.__path__._recalculate()`
|
|
# as it should not be necessary
|
|
import pelican
|
|
|
|
old_path = pelican.__path__[:]
|
|
try:
|
|
pelican.__path__.append(os.path.join(path, "pelican"))
|
|
yield
|
|
finally:
|
|
pelican.__path__ = old_path
|
|
|
|
|
|
class PluginTest(unittest.TestCase):
|
|
_PLUGIN_FOLDER = os.path.join(
|
|
os.path.abspath(os.path.dirname(__file__)), "dummy_plugins"
|
|
)
|
|
_NS_PLUGIN_FOLDER = os.path.join(_PLUGIN_FOLDER, "namespace_plugin")
|
|
_NORMAL_PLUGIN_FOLDER = os.path.join(_PLUGIN_FOLDER, "normal_plugin")
|
|
|
|
def test_namespace_path_modification(self):
|
|
import pelican
|
|
import pelican.plugins
|
|
|
|
old_path = pelican.__path__[:]
|
|
|
|
# not existing path
|
|
path = os.path.join(self._PLUGIN_FOLDER, "foo")
|
|
with tmp_namespace_path(path):
|
|
self.assertIn(os.path.join(path, "pelican"), pelican.__path__)
|
|
# foo/pelican does not exist, so it won't propagate
|
|
self.assertNotIn(
|
|
os.path.join(path, "pelican", "plugins"), pelican.plugins.__path__
|
|
)
|
|
# verify that we restored path back
|
|
self.assertEqual(pelican.__path__, old_path)
|
|
|
|
# existing path
|
|
with tmp_namespace_path(self._NS_PLUGIN_FOLDER):
|
|
self.assertIn(
|
|
os.path.join(self._NS_PLUGIN_FOLDER, "pelican"), pelican.__path__
|
|
)
|
|
# /namespace_plugin/pelican exists, so it should be in
|
|
self.assertIn(
|
|
os.path.join(self._NS_PLUGIN_FOLDER, "pelican", "plugins"),
|
|
pelican.plugins.__path__,
|
|
)
|
|
self.assertEqual(pelican.__path__, old_path)
|
|
|
|
def test_get_namespace_plugins(self):
|
|
# existing namespace plugins
|
|
existing_ns_plugins = get_namespace_plugins()
|
|
|
|
# with plugin
|
|
with tmp_namespace_path(self._NS_PLUGIN_FOLDER):
|
|
ns_plugins = get_namespace_plugins()
|
|
self.assertEqual(len(ns_plugins), len(existing_ns_plugins) + 1)
|
|
self.assertIn("pelican.plugins.ns_plugin", ns_plugins)
|
|
self.assertEqual(
|
|
ns_plugins["pelican.plugins.ns_plugin"].NAME, "namespace plugin"
|
|
)
|
|
|
|
# should be back to existing namespace plugins outside `with`
|
|
ns_plugins = get_namespace_plugins()
|
|
self.assertEqual(ns_plugins, existing_ns_plugins)
|
|
|
|
def test_load_plugins(self):
|
|
def get_plugin_names(plugins):
|
|
return {get_plugin_name(p) for p in plugins}
|
|
|
|
# existing namespace plugins
|
|
existing_ns_plugins = load_plugins({})
|
|
|
|
with tmp_namespace_path(self._NS_PLUGIN_FOLDER):
|
|
# with no `PLUGINS` setting, load namespace plugins
|
|
plugins = load_plugins({})
|
|
self.assertEqual(len(plugins), len(existing_ns_plugins) + 1, plugins)
|
|
self.assertEqual(
|
|
{"pelican.plugins.ns_plugin"} | get_plugin_names(existing_ns_plugins),
|
|
get_plugin_names(plugins),
|
|
)
|
|
|
|
# disable namespace plugins with `PLUGINS = []`
|
|
SETTINGS = {"PLUGINS": []}
|
|
plugins = load_plugins(SETTINGS)
|
|
self.assertEqual(len(plugins), 0, plugins)
|
|
|
|
# with `PLUGINS`, load only specified plugins
|
|
|
|
# normal plugin
|
|
SETTINGS = {
|
|
"PLUGINS": ["normal_plugin"],
|
|
"PLUGIN_PATHS": [self._NORMAL_PLUGIN_FOLDER],
|
|
}
|
|
plugins = load_plugins(SETTINGS)
|
|
self.assertEqual(len(plugins), 1, plugins)
|
|
self.assertEqual({"normal_plugin"}, get_plugin_names(plugins))
|
|
|
|
# normal submodule/subpackage plugins
|
|
SETTINGS = {
|
|
"PLUGINS": [
|
|
"normal_submodule_plugin.subplugin",
|
|
"normal_submodule_plugin.subpackage.subpackage",
|
|
],
|
|
"PLUGIN_PATHS": [self._NORMAL_PLUGIN_FOLDER],
|
|
}
|
|
plugins = load_plugins(SETTINGS)
|
|
self.assertEqual(len(plugins), 2, plugins)
|
|
self.assertEqual(
|
|
{
|
|
"normal_submodule_plugin.subplugin",
|
|
"normal_submodule_plugin.subpackage.subpackage",
|
|
},
|
|
get_plugin_names(plugins),
|
|
)
|
|
|
|
# ensure normal plugins are loaded only once
|
|
SETTINGS = {
|
|
"PLUGINS": ["normal_plugin"],
|
|
"PLUGIN_PATHS": [self._NORMAL_PLUGIN_FOLDER],
|
|
}
|
|
plugins = load_plugins(SETTINGS)
|
|
for plugin in load_plugins(SETTINGS):
|
|
# The second load_plugins() should return the same plugin
|
|
# objects as the first one
|
|
self.assertIn(plugin, plugins)
|
|
|
|
# namespace plugin short
|
|
SETTINGS = {"PLUGINS": ["ns_plugin"]}
|
|
plugins = load_plugins(SETTINGS)
|
|
self.assertEqual(len(plugins), 1, plugins)
|
|
self.assertEqual({"pelican.plugins.ns_plugin"}, get_plugin_names(plugins))
|
|
|
|
# namespace plugin long
|
|
SETTINGS = {"PLUGINS": ["pelican.plugins.ns_plugin"]}
|
|
plugins = load_plugins(SETTINGS)
|
|
self.assertEqual(len(plugins), 1, plugins)
|
|
self.assertEqual({"pelican.plugins.ns_plugin"}, get_plugin_names(plugins))
|
|
|
|
# normal and namespace plugin
|
|
SETTINGS = {
|
|
"PLUGINS": ["normal_plugin", "ns_plugin"],
|
|
"PLUGIN_PATHS": [self._NORMAL_PLUGIN_FOLDER],
|
|
}
|
|
plugins = load_plugins(SETTINGS)
|
|
self.assertEqual(len(plugins), 2, plugins)
|
|
self.assertEqual(
|
|
{"normal_plugin", "pelican.plugins.ns_plugin"},
|
|
get_plugin_names(plugins),
|
|
)
|
|
|
|
def test_get_plugin_name(self):
|
|
self.assertEqual(
|
|
get_plugin_name(normal_plugin),
|
|
"pelican.tests.dummy_plugins.normal_plugin.normal_plugin",
|
|
)
|
|
|
|
class NoopPlugin:
|
|
def register(self):
|
|
pass
|
|
|
|
self.assertEqual(
|
|
get_plugin_name(NoopPlugin),
|
|
"PluginTest.test_get_plugin_name.<locals>.NoopPlugin",
|
|
)
|
|
self.assertEqual(
|
|
get_plugin_name(NoopPlugin()),
|
|
"PluginTest.test_get_plugin_name.<locals>.NoopPlugin",
|
|
)
|
|
|
|
def test_plugin_enabled(self):
|
|
def get_plugin_names(plugins):
|
|
return [get_plugin_name(p) for p in plugins]
|
|
|
|
with tmp_namespace_path(self._NS_PLUGIN_FOLDER):
|
|
# with no `PLUGINS` setting, load namespace plugins
|
|
SETTINGS = {}
|
|
plugins = get_plugin_names(load_plugins(SETTINGS))
|
|
self.assertTrue(plugin_enabled("ns_plugin", plugins))
|
|
self.assertTrue(plugin_enabled("pelican.plugins.ns_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("normal_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("unknown", plugins))
|
|
|
|
# disable namespace plugins with `PLUGINS = []`
|
|
SETTINGS = {"PLUGINS": []}
|
|
plugins = get_plugin_names(load_plugins(SETTINGS))
|
|
self.assertFalse(plugin_enabled("ns_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("pelican.plugins.ns_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("normal_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("unknown", plugins))
|
|
|
|
# with `PLUGINS`, load only specified plugins
|
|
|
|
# normal plugin
|
|
SETTINGS = {
|
|
"PLUGINS": ["normal_plugin"],
|
|
"PLUGIN_PATHS": [self._NORMAL_PLUGIN_FOLDER],
|
|
}
|
|
plugins = get_plugin_names(load_plugins(SETTINGS))
|
|
self.assertFalse(plugin_enabled("ns_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("pelican.plugins.ns_plugin", plugins))
|
|
self.assertTrue(plugin_enabled("normal_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("unknown", plugins))
|
|
|
|
# normal submodule/subpackage plugins
|
|
SETTINGS = {
|
|
"PLUGINS": [
|
|
"normal_submodule_plugin.subplugin",
|
|
"normal_submodule_plugin.subpackage.subpackage",
|
|
],
|
|
"PLUGIN_PATHS": [self._NORMAL_PLUGIN_FOLDER],
|
|
}
|
|
plugins = get_plugin_names(load_plugins(SETTINGS))
|
|
self.assertFalse(plugin_enabled("ns_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("pelican.plugins.ns_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("normal_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("unknown", plugins))
|
|
|
|
# namespace plugin short
|
|
SETTINGS = {"PLUGINS": ["ns_plugin"]}
|
|
plugins = get_plugin_names(load_plugins(SETTINGS))
|
|
self.assertTrue(plugin_enabled("ns_plugin", plugins))
|
|
self.assertTrue(plugin_enabled("pelican.plugins.ns_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("normal_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("unknown", plugins))
|
|
|
|
# namespace plugin long
|
|
SETTINGS = {"PLUGINS": ["pelican.plugins.ns_plugin"]}
|
|
plugins = get_plugin_names(load_plugins(SETTINGS))
|
|
self.assertTrue(plugin_enabled("ns_plugin", plugins))
|
|
self.assertTrue(plugin_enabled("pelican.plugins.ns_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("normal_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("unknown", plugins))
|
|
|
|
# normal and namespace plugin
|
|
SETTINGS = {
|
|
"PLUGINS": ["normal_plugin", "ns_plugin"],
|
|
"PLUGIN_PATHS": [self._NORMAL_PLUGIN_FOLDER],
|
|
}
|
|
plugins = get_plugin_names(load_plugins(SETTINGS))
|
|
self.assertTrue(plugin_enabled("ns_plugin", plugins))
|
|
self.assertTrue(plugin_enabled("pelican.plugins.ns_plugin", plugins))
|
|
self.assertTrue(plugin_enabled("normal_plugin", plugins))
|
|
self.assertFalse(plugin_enabled("unknown", plugins))
|
|
|
|
def test_blinker_is_ordered(self):
|
|
"""ensure that call order is connetion order"""
|
|
dummy_signal = signal("dummpy_signal")
|
|
|
|
functions = []
|
|
expected = []
|
|
for i in range(50):
|
|
# function appends value of i to a list
|
|
def func(input, i=i):
|
|
input.append(i)
|
|
|
|
functions.append(func)
|
|
# we expect functions to be run in the connection order
|
|
dummy_signal.connect(func)
|
|
expected.append(i)
|
|
|
|
input = []
|
|
dummy_signal.send(input)
|
|
self.assertEqual(input, expected)
|