summaryrefslogtreecommitdiff
path: root/tests/test_plugins.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_plugins.py')
-rw-r--r--tests/test_plugins.py217
1 files changed, 217 insertions, 0 deletions
diff --git a/tests/test_plugins.py b/tests/test_plugins.py
new file mode 100644
index 00000000..9c5a037d
--- /dev/null
+++ b/tests/test_plugins.py
@@ -0,0 +1,217 @@
+"""Tests for plugins."""
+
+import os.path
+
+import coverage
+from coverage.codeunit import CodeUnit
+from coverage.parser import CodeParser
+from coverage.plugin import Plugins, overrides
+
+from tests.coveragetest import CoverageTest
+
+
+class FakeConfig(object):
+ """A fake config for use in tests."""
+
+ def __init__(self, plugin, options):
+ self.plugin = plugin
+ self.options = options
+ self.asked_for = []
+
+ def get_plugin_options(self, module):
+ """Just return the options for `module` if this is the right module."""
+ self.asked_for.append(module)
+ if module == self.plugin:
+ return self.options
+ else:
+ return {}
+
+
+class PluginUnitTest(CoverageTest):
+ """Test Plugins.load_plugins directly."""
+
+ def test_importing_and_configuring(self):
+ self.make_file("plugin1.py", """\
+ from coverage import CoveragePlugin
+
+ class Plugin(CoveragePlugin):
+ def __init__(self, options):
+ super(Plugin, self).__init__(options)
+ self.this_is = "me"
+ """)
+
+ config = FakeConfig("plugin1", {'a':'hello'})
+ plugins = list(Plugins.load_plugins(["plugin1"], config))
+
+ self.assertEqual(len(plugins), 1)
+ self.assertEqual(plugins[0].this_is, "me")
+ self.assertEqual(plugins[0].options, {'a':'hello'})
+ self.assertEqual(config.asked_for, ['plugin1'])
+
+ def test_importing_and_configuring_more_than_one(self):
+ self.make_file("plugin1.py", """\
+ from coverage import CoveragePlugin
+
+ class Plugin(CoveragePlugin):
+ def __init__(self, options):
+ super(Plugin, self).__init__(options)
+ self.this_is = "me"
+ """)
+ self.make_file("plugin2.py", """\
+ from coverage import CoveragePlugin
+
+ class Plugin(CoveragePlugin):
+ pass
+ """)
+
+ config = FakeConfig("plugin1", {'a':'hello'})
+ plugins = list(Plugins.load_plugins(["plugin1", "plugin2"], config))
+
+ self.assertEqual(len(plugins), 2)
+ self.assertEqual(plugins[0].this_is, "me")
+ self.assertEqual(plugins[0].options, {'a':'hello'})
+ self.assertEqual(plugins[1].options, {})
+ self.assertEqual(config.asked_for, ['plugin1', 'plugin2'])
+
+ def test_cant_import(self):
+ with self.assertRaises(ImportError):
+ _ = Plugins.load_plugins(["plugin_not_there"], None)
+
+ def test_ok_to_not_define_plugin(self):
+ self.make_file("plugin2.py", """\
+ from coverage import CoveragePlugin
+
+ Nothing = 0
+ """)
+ plugins = list(Plugins.load_plugins(["plugin2"], None))
+ self.assertEqual(plugins, [])
+
+
+class PluginTest(CoverageTest):
+ """Test plugins through the Coverage class."""
+
+ def test_plugin_imported(self):
+ # Prove that a plugin will be imported.
+ self.make_file("my_plugin.py", """\
+ with open("evidence.out", "w") as f:
+ f.write("we are here!")
+ """)
+
+ self.assert_doesnt_exist("evidence.out")
+ _ = coverage.Coverage(plugins=["my_plugin"])
+
+ with open("evidence.out") as f:
+ self.assertEqual(f.read(), "we are here!")
+
+ def test_missing_plugin_raises_import_error(self):
+ # Prove that a missing plugin will raise an ImportError.
+ with self.assertRaises(ImportError):
+ cov = coverage.Coverage(plugins=["does_not_exist_woijwoicweo"])
+ cov.start()
+
+ def test_bad_plugin_isnt_hidden(self):
+ # Prove that a plugin with an error in it will raise the error.
+ self.make_file("plugin_over_zero.py", """\
+ 1/0
+ """)
+ with self.assertRaises(ZeroDivisionError):
+ _ = coverage.Coverage(plugins=["plugin_over_zero"])
+
+ def test_importing_myself(self):
+ self.make_file("simple.py", """\
+ import try_xyz
+ a = 1
+ b = 2
+ """)
+ self.make_file("try_xyz.py", """\
+ c = 3
+ d = 4
+ """)
+
+ cov = coverage.Coverage(plugins=["tests.test_plugins"])
+
+ # Import the python file, executing it.
+ self.start_import_stop(cov, "simple")
+
+ _, statements, missing, _ = cov.analysis("simple.py")
+ self.assertEqual(statements, [1,2,3])
+ self.assertEqual(missing, [])
+ _, statements, _, _ = cov.analysis("/src/try_ABC.zz")
+ self.assertEqual(statements, [105, 106, 107, 205, 206, 207])
+
+
+class Plugin(coverage.CoveragePlugin):
+ def trace_judge(self, disp):
+ if "xyz.py" in disp.original_filename:
+ disp.trace = True
+ disp.source_filename = os.path.join(
+ "/src",
+ os.path.basename(
+ disp.original_filename.replace("xyz.py", "ABC.zz")
+ )
+ )
+
+ def line_number_range(self, frame):
+ lineno = frame.f_lineno
+ return lineno*100+5, lineno*100+7
+
+ def code_unit_class(self, filename):
+ return PluginCodeUnit
+
+class PluginCodeUnit(CodeUnit):
+ def get_parser(self, exclude=None):
+ return PluginParser()
+
+class PluginParser(CodeParser):
+ def parse_source(self):
+ return set([105, 106, 107, 205, 206, 207]), set([])
+
+
+class OverridesTest(CoverageTest):
+ """Test plugins.py:overrides."""
+
+ run_in_temp_dir = False
+
+ def test_overrides(self):
+ class SomeBase(object):
+ """Base class, two base methods."""
+ def method1(self):
+ pass
+
+ def method2(self):
+ pass
+
+ class Derived1(SomeBase):
+ """Simple single inheritance."""
+ def method1(self):
+ pass
+
+ self.assertTrue(overrides(Derived1(), "method1", SomeBase))
+ self.assertFalse(overrides(Derived1(), "method2", SomeBase))
+
+ class FurtherDerived1(Derived1):
+ """Derive again from Derived1, inherit its method1."""
+ pass
+
+ self.assertTrue(overrides(FurtherDerived1(), "method1", SomeBase))
+ self.assertFalse(overrides(FurtherDerived1(), "method2", SomeBase))
+
+ class FurtherDerived2(Derived1):
+ """Override the overridden method."""
+ def method1(self):
+ pass
+
+ self.assertTrue(overrides(FurtherDerived2(), "method1", SomeBase))
+ self.assertFalse(overrides(FurtherDerived2(), "method2", SomeBase))
+
+ class Mixin(object):
+ """A mixin that overrides method1."""
+ def method1(self):
+ pass
+
+ class Derived2(Mixin, SomeBase):
+ """A class that gets the method from the mixin."""
+ pass
+
+ self.assertTrue(overrides(Derived2(), "method1", SomeBase))
+ self.assertFalse(overrides(Derived2(), "method2", SomeBase))