#!/usr/bin/env python
import sys
import os
import unittest
from types import ModuleType
import mock
from straight.plugin import loaders, manager
try:
skipIf = unittest.skipIf
except AttributeError:
import functools
class SkipTest(Exception):
"""
Raise this exception in a test to skip it.
Usually you can use TestResult.skip() or one of the skipping decorators
instead of raising this directly.
"""
def skipIf(cond, reason):
"""
Unconditionally skip a test.
"""
def decorator(test_item):
if cond:
if not isinstance(test_item, type):
@functools.wraps(test_item)
def skip_wrapper(*args, **kwargs):
pass
test_item = skip_wrapper
test_item.__unittest_skip__ = True
test_item.__unittest_skip_why__ = reason
return test_item
else:
return test_item
return decorator
class LoaderTestCaseMixin(object):
paths = []
def setUp(self):
for path in self.paths:
if isinstance(path, tuple):
path = os.path.join(*path)
sys.path.append(path)
super(LoaderTestCaseMixin, self).setUp()
def tearDown(self):
for path in self.paths:
del sys.path[-1]
for modname in list(sys.modules):
if modname.startswith('testplugin'):
del sys.modules[modname]
class ModuleLoaderTestCase(LoaderTestCaseMixin, unittest.TestCase):
paths = (
os.path.join(os.path.dirname(__file__), 'test-packages', 'more-test-plugins'),
os.path.join(os.path.dirname(__file__), 'test-packages', 'some-test-plugins'),
)
def setUp(self):
self.loader = loaders.ModuleLoader()
super(ModuleLoaderTestCase, self).setUp()
def test_load(self):
modules = list(self.loader.load('testplugin'))
assert len(modules) == 2, modules
def test_plugin(self):
assert self.loader.load('testplugin')[0].do(1) == 2
class ImpliedNamespaceModuleTestCase(LoaderTestCaseMixin, unittest.TestCase):
paths = (
os.path.join(os.path.dirname(__file__), 'test-packages', 'pep-420-plugins'),
)
def setUp(self):
self.loader = loaders.ModuleLoader()
super(ImpliedNamespaceModuleTestCase, self).setUp()
@skipIf(sys.version_info < (3, 3),"Python < 3.3")
def test_load(self):
modules = list(self.loader.load('testplugin'))
assert len(modules) == 1, modules
@skipIf(sys.version_info < (3, 3), "Python < 3.3")
def test_plugin(self):
r = self.loader.load('testplugin')[0].do("implied namespace packages are")
self.assertEqual(r, "implied namespace packages are from pep-420")
class ImplyLoaderTestCase(LoaderTestCaseMixin, unittest.TestCase):
paths = (
os.path.join(os.path.dirname(__file__), 'test-packages', 'imply-plugins'),
)
def setUp(self):
self.loader = loaders.ModuleLoader()
super(ImplyLoaderTestCase, self).setUp()
def test_load(self):
modules = list(self.loader.load('testplugin'))
assert len(modules) == 1, modules
assert modules[0].__name__ == 'testplugin_2.bar', modules[0].__name__
class ObjectLoaderTestCase(LoaderTestCaseMixin, unittest.TestCase):
paths = (
os.path.join(os.path.dirname(__file__), 'test-packages', 'more-test-plugins'),
os.path.join(os.path.dirname(__file__), 'test-packages', 'some-test-plugins'),
)
def setUp(self):
self.loader = loaders.ObjectLoader()
super(ObjectLoaderTestCase, self).setUp()
def test_load_all(self):
objects = list(self.loader.load('testplugin'))
self.assertEqual(len(objects), 2, str(objects)[:100] + ' ...')
class ClassLoaderTestCase(LoaderTestCaseMixin, unittest.TestCase):
paths = (
os.path.join(os.path.dirname(__file__), 'test-packages', 'class-test-plugins'),
)
def setUp(self):
self.loader = loaders.ClassLoader()
super(ClassLoaderTestCase, self).setUp()
def test_all_classes(self):
classes = list(self.loader.load('testplugin'))
self.assertEqual(len(classes), 3)
def test_subclasses(self):
from testplugin import testclasses
classes = list(self.loader.load('testplugin', subclasses=testclasses.A))
self.assertEqual(len(classes), 1)
self.assertTrue(classes[0] is testclasses.A1)
class PriorityLoaderTestCase(LoaderTestCaseMixin, unittest.TestCase):
paths = (
os.path.join(os.path.dirname(__file__), 'test-packages', 'class-test-plugins'),
)
def setUp(self):
self.loader = loaders.ClassLoader()
super(PriorityLoaderTestCase, self).setUp()
def test_all_classes(self):
classes = list(self.loader.load('testplugin'))
self.assertEqual(classes[0].__name__, 'B')
self.assertEqual(classes[1].__name__, 'A')
self.assertEqual(classes[2].__name__, 'A1')
class PackageLoaderTestCase(LoaderTestCaseMixin, unittest.TestCase):
paths = (
os.path.join(os.path.dirname(__file__), 'test-packages', 'package-test-plugins'),
)
def setUp(self):
self.loader = loaders.ModuleLoader()
super(PackageLoaderTestCase, self).setUp()
def test_find_packages(self):
filepaths = list(self.loader._findPluginFilePaths('testplugin'))
self.assertEqual(len(filepaths), 3)
def test_load_packages(self):
packages = list(self.loader.load('testplugin'))
self.assertEqual(len(packages), 3)
for pkg in packages:
self.assertTrue(isinstance(pkg, ModuleType))
def test_plugin(self):
plugins = self.loader.load('testplugin')
results = set(p.do(1) for p in plugins)
self.assertEqual(results, set((2, 3, 4)))
class RecursingPackageLoaderTestCase(LoaderTestCaseMixin, unittest.TestCase):
paths = (
os.path.join(os.path.dirname(__file__), 'test-packages', 'package-test-plugins'),
)
def setUp(self):
self.loader = loaders.ModuleLoader(recurse=True)
super(RecursingPackageLoaderTestCase, self).setUp()
def test_find_packages(self):
filepaths = list(self.loader._findPluginFilePaths('testplugin'))
self.assertEqual(len(filepaths), 4)
def test_load_packages(self):
packages = list(self.loader.load('testplugin'))
self.assertEqual(len(packages), 4)
for pkg in packages:
self.assertTrue(isinstance(pkg, ModuleType))
def test_plugin(self):
plugins = self.loader.load('testplugin')
results = set(p.do(1) for p in plugins)
self.assertEqual(results, set((2, 3, 4, 'quu')))
class PluginManagerTestCase(unittest.TestCase):
def setUp(self):
self.m = manager.PluginManager([
mock.Mock(),
mock.Mock(),
])
def test_first(self):
self.m._plugins[0].x.return_value = 1
self.assertEqual(1, self.m.first('x', 'a'))
self.assertFalse(self.m._plugins[1].called)
self.assertTrue(self.m._plugins[0].called_with('a'))
def test_pipe(self):
def plus_one(x):
return x + 1
self.m._plugins[0].x.side_effect = plus_one
self.m._plugins[1].x.side_effect = plus_one
self.assertEqual(3, self.m.pipe('x', 1))
def test_call(self):
results = self.m.call('x', 1)
self.assertTrue(self.m._plugins[0].called_with('a'))
self.assertTrue(self.m._plugins[1].x.called_with(1))
def test_produce(self):
products = self.m.produce(1, 2)
assert products[0] is self.m._plugins[0].return_value
self.m._plugins[0].called_with(1, 2)
assert products[1] is self.m._plugins[1].return_value
self.m._plugins[1].called_with(1, 2)
if __name__ == '__main__':
unittest.main()