summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt2
-rw-r--r--Makefile1
-rw-r--r--coverage/codeunit.py11
-rw-r--r--test/modules/aa/__init__.py1
-rw-r--r--test/modules/aa/afile.py1
-rw-r--r--test/modules/aa/bb/__init__.py1
-rw-r--r--test/modules/aa/bb/bfile.py1
-rw-r--r--test/modules/aa/bb/cc/__init__.py0
-rw-r--r--test/modules/aa/bb/cc/cfile.py1
-rw-r--r--test/test_codeunit.py60
10 files changed, 76 insertions, 3 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 7e7a278d..8e1c6e0d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -11,6 +11,8 @@ Version 3.0
- Tabs are now properly converted in HTML reports. Previously indentation was
lost.
+- Nested modules now get a proper flat_rootname. Thanks, Christian Heimes.
+
Version 3.0b3, 16 May 2009
--------------------------
diff --git a/Makefile b/Makefile
index 9cbdb1a3..e1d04bc5 100644
--- a/Makefile
+++ b/Makefile
@@ -26,6 +26,7 @@ LINTABLE_TESTS = \
test/coveragetest.py \
test/test_api.py \
test/test_cmdline.py \
+ test/test_codeunit.py \
test/test_data.py \
test/test_execfile.py \
test/test_farm.py \
diff --git a/coverage/codeunit.py b/coverage/codeunit.py
index a4e029b7..87782cd0 100644
--- a/coverage/codeunit.py
+++ b/coverage/codeunit.py
@@ -66,7 +66,7 @@ class CodeUnit:
self.filename = file_locator.canonical_filename(f)
if hasattr(morf, '__name__'):
- n = morf.__name__
+ n = modname = morf.__name__
self.relative = True
else:
n = os.path.splitext(morf)[0]
@@ -76,7 +76,9 @@ class CodeUnit:
else:
self.relative = True
n = rel
+ modname = None
self.name = n
+ self.modname = modname
def __repr__(self):
return "<CodeUnit name=%r filename=%r>" % (self.name, self.filename)
@@ -94,8 +96,11 @@ class CodeUnit:
For example, the file a/b/c.py might return 'a_b_c'
"""
- root = os.path.splitdrive(os.path.splitext(self.name)[0])[1]
- return root.replace('\\', '_').replace('/', '_')
+ if self.modname:
+ return self.modname.replace('.', '_')
+ else:
+ root = os.path.splitdrive(os.path.splitext(self.name)[0])[1]
+ return root.replace('\\', '_').replace('/', '_')
def source_file(self):
"""Return an open file for reading the source of the code unit."""
diff --git a/test/modules/aa/__init__.py b/test/modules/aa/__init__.py
new file mode 100644
index 00000000..77593d8f
--- /dev/null
+++ b/test/modules/aa/__init__.py
@@ -0,0 +1 @@
+# aa
diff --git a/test/modules/aa/afile.py b/test/modules/aa/afile.py
new file mode 100644
index 00000000..3f0e38d1
--- /dev/null
+++ b/test/modules/aa/afile.py
@@ -0,0 +1 @@
+# afile.py
diff --git a/test/modules/aa/bb/__init__.py b/test/modules/aa/bb/__init__.py
new file mode 100644
index 00000000..ffbe6240
--- /dev/null
+++ b/test/modules/aa/bb/__init__.py
@@ -0,0 +1 @@
+# bb
diff --git a/test/modules/aa/bb/bfile.py b/test/modules/aa/bb/bfile.py
new file mode 100644
index 00000000..90875404
--- /dev/null
+++ b/test/modules/aa/bb/bfile.py
@@ -0,0 +1 @@
+# bfile.py
diff --git a/test/modules/aa/bb/cc/__init__.py b/test/modules/aa/bb/cc/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/modules/aa/bb/cc/__init__.py
diff --git a/test/modules/aa/bb/cc/cfile.py b/test/modules/aa/bb/cc/cfile.py
new file mode 100644
index 00000000..79764751
--- /dev/null
+++ b/test/modules/aa/bb/cc/cfile.py
@@ -0,0 +1 @@
+# cfile.py
diff --git a/test/test_codeunit.py b/test/test_codeunit.py
new file mode 100644
index 00000000..d03ff8d9
--- /dev/null
+++ b/test/test_codeunit.py
@@ -0,0 +1,60 @@
+"""Tests for coverage.codeunit"""
+
+import os, sys
+
+from coverage.codeunit import code_unit_factory
+from coverage.files import FileLocator
+from coveragetest import CoverageTest
+
+# pylint: disable-msg=F0401
+# Unable to import 'aa' (No module named aa)
+
+class CodeUnitTest(CoverageTest):
+ """Tests for coverage.codeunit"""
+
+ def setUp(self):
+ super(CodeUnitTest, self).setUp()
+ # Parent class saves and restores sys.path, we can just modify it.
+ testmods = self.nice_file(os.path.dirname(__file__), 'modules')
+ sys.path.append(testmods)
+
+ def test_filenames(self):
+ acu = code_unit_factory("aa/afile.py", FileLocator())
+ bcu = code_unit_factory("aa/bb/bfile.py", FileLocator())
+ ccu = code_unit_factory("aa/bb/cc/cfile.py", FileLocator())
+ self.assertEqual(acu[0].name, "aa/afile")
+ self.assertEqual(bcu[0].name, "aa/bb/bfile")
+ self.assertEqual(ccu[0].name, "aa/bb/cc/cfile")
+ self.assertEqual(acu[0].flat_rootname(), "aa_afile")
+ self.assertEqual(bcu[0].flat_rootname(), "aa_bb_bfile")
+ self.assertEqual(ccu[0].flat_rootname(), "aa_bb_cc_cfile")
+ self.assertEqual(acu[0].source_file().read(), "# afile.py\n")
+ self.assertEqual(bcu[0].source_file().read(), "# bfile.py\n")
+ self.assertEqual(ccu[0].source_file().read(), "# cfile.py\n")
+
+ def test_modules(self):
+ import aa, aa.bb, aa.bb.cc
+ cu = code_unit_factory([aa, aa.bb, aa.bb.cc], FileLocator())
+ self.assertEqual(cu[0].name, "aa")
+ self.assertEqual(cu[1].name, "aa.bb")
+ self.assertEqual(cu[2].name, "aa.bb.cc")
+ self.assertEqual(cu[0].flat_rootname(), "aa")
+ self.assertEqual(cu[1].flat_rootname(), "aa_bb")
+ self.assertEqual(cu[2].flat_rootname(), "aa_bb_cc")
+ self.assertEqual(cu[0].source_file().read(), "# aa\n")
+ self.assertEqual(cu[1].source_file().read(), "# bb\n")
+ self.assertEqual(cu[2].source_file().read(), "") # yes, empty
+
+ def test_module_files(self):
+ import aa.afile, aa.bb.bfile, aa.bb.cc.cfile
+ cu = code_unit_factory([aa.afile, aa.bb.bfile, aa.bb.cc.cfile],
+ FileLocator())
+ self.assertEqual(cu[0].name, "aa.afile")
+ self.assertEqual(cu[1].name, "aa.bb.bfile")
+ self.assertEqual(cu[2].name, "aa.bb.cc.cfile")
+ self.assertEqual(cu[0].flat_rootname(), "aa_afile")
+ self.assertEqual(cu[1].flat_rootname(), "aa_bb_bfile")
+ self.assertEqual(cu[2].flat_rootname(), "aa_bb_cc_cfile")
+ self.assertEqual(cu[0].source_file().read(), "# afile.py\n")
+ self.assertEqual(cu[1].source_file().read(), "# bfile.py\n")
+ self.assertEqual(cu[2].source_file().read(), "# cfile.py\n")