Commits

Anonymous committed 607d83f

Added stats for modules

  • Participants
  • Parent commits 287837f

Comments (0)

Files changed (3)

             node = compiler.parse(code_or_node)
         except TypeError:
             node = code_or_node
+            in_module = False
+        else:
+            in_module = True
 
         self.score = 1
         self._in_conditional = False
-        self.stack = []
-        self.stats = []
+        self.stats = StatsCollection()
         for child in node.getChildNodes():
             compiler.walk(child, self, walker=self)
 
+        if in_module:
+            end_line = max(1, code_or_node.count('\n') + 1)
+            self.stats.add(Stats(name='<module>',
+                                 score=self.score,
+                                 start_line=1,
+                                 end_line=end_line))
+
     def dispatchChildren(self, node):
-        self.stack.append(node)
         for child in node.getChildNodes():
             self.dispatch(child)
-        self.stack.pop()
 
     def visitFunction(self, node):
         #if not hasattr(node, 'name'): # lambdas
                       score=score,
                       start_line=node.lineno,
                       end_line=self.highest_line_in_node(node))
-        self.stats.append(stats)
+        self.stats.add(stats)
 
     #visitLambda = visitFunction
 
     def visitClass(self, node):
         complexity = Complexity(node)
-        self.stats.append(Stats(name=node.name,
-                                score=complexity.score,
-                                start_line=node.lineno,
-                                end_line=self.highest_line_in_node(node)))
-        for stats_instance in complexity.stats:
+        self.stats.add(Stats(name=node.name,
+                             score=complexity.score,
+                             start_line=node.lineno,
+                             end_line=self.highest_line_in_node(node)))
+        for stats_instance in complexity.stats.all():
             stats_instance.name = '%s.%s' % (node.name, stats_instance.name)
-            self.stats.append(stats_instance)
+            self.stats.add(stats_instance)
 
     def highest_line_in_node(self, node, highest=0):
         children = node.getChildNodes()
         self.score += len(node.handlers)
 
 
+class StatsCollection:
+    def __init__(self):
+        self._stats = []
+
+    def add(self, stats):
+        self._stats.append(stats)
+
+    def all(self):
+        return self._stats[:]
+
+    def named(self, name):
+        return [s for s in self._stats if s.name == name][0]
+
+
 class Stats:
     def __init__(self, name, score, start_line, end_line):
         self.name = name
         self.start_line = start_line
         self.end_line = end_line
 
+    def __repr__(self):
+        return 'Stats(name=%s, score=%s, start_line=%s, end_line=%s)' % (
+            repr(self.name),
+            repr(self.score),
+            repr(self.start_line),
+            repr(self.end_line))
+
 
 def measure_complexity(ast, module_name=None):
     return CCVisitor(ast, description=module_name).stats

tests/test_integration.py

             def foo():
                 x = lambda: x if x else x
                 y if y else y
-            """).stats[0].score == 3
+            """).stats.named('foo').score == 3
 
     def test_a_big_hairy_mess(self):
         assert complexity(

tests/test_scoped_objects.py

 from tests.utils import complexity
 
 
+class describe_modules:
+    def test_that_they_are_scored(self):
+        assert complexity(
+            """
+            a if a else a
+            """).stats.named('<module>').score == 2
+        assert complexity(
+            """
+                0 if x else 1 if y else 2
+            """).stats.named('<module>').score == 3
+
+    def test_that_they_know_their_names(self):
+        assert complexity("").stats.named('<module>').name == '<module>'
+
+    def test_that_they_know_their_line_range(self):
+        stats = complexity("").stats.named('<module>')
+        assert stats.start_line == 1
+        assert stats.end_line == 1
+
+        stats = complexity(
+            """
+            a
+            """).stats.named('<module>')
+        print '-%s-' % (
+            """
+            a
+            """)
+        assert stats.start_line == 1
+        assert stats.end_line == 3
+
+    def test_module_with_function_in_it(self):
+        assert complexity(
+            """
+            a if a else a
+            def foo():
+                a if a else a
+            a if a else a
+            """).stats.named('<module>').score == 3
+
+
 class describe_functions:
     def test_that_they_are_scored(self):
         assert complexity(
             """
             def foo():
                 0 if x else 1
-            """).stats[0].score == 2
+            """).stats.named('foo').score == 2
         assert complexity(
             """
             def foo():
                 0 if x else 1 if y else 2
-            """).stats[0].score == 3
+            """).stats.named('foo').score == 3
 
     def test_that_they_know_their_names(self):
         assert complexity(
             """
             def foo(): pass
-            """).stats[0].name == 'foo'
+            """).stats.named('foo').name == 'foo'
 
     def test_that_they_know_their_line_range(self):
-        stats = complexity("def foo(): pass").stats[0]
+        stats = complexity("def foo(): pass").stats.named('foo')
         assert stats.start_line == 1
         assert stats.end_line == 1
 
         stats = complexity(
             """
             def foo(): pass
-            """).stats[0]
+            """).stats.named('foo')
         assert stats.start_line == 2
         assert stats.end_line == 2
 
             """
             class Foo:
                 0 if x else 1
-            """).stats[0].score == 2
+            """).stats.named('Foo').score == 2
         assert complexity(
             """
             class Foo:
                 0 if x else 1 if y else 2
-            """).stats[0].score == 3
+            """).stats.named('Foo').score == 3
 
     def test_that_they_know_their_names(self):
         assert complexity(
             """
             class Foo: pass
-            """).stats[0].name == 'Foo'
+            """).stats.named('Foo').name == 'Foo'
 
     def test_that_they_know_their_line_range(self):
-        stats = complexity("class Foo: pass").stats[0]
+        stats = complexity("class Foo: pass").stats.named('Foo')
         assert stats.start_line == 1
         assert stats.end_line == 1
 
             """
             class Foo:
                 pass
-            """).stats[0]
+            """).stats.named('Foo')
         assert stats.start_line == 2
         assert stats.end_line == 3
 
                 0 if x else 1
                 def foo(self): pass
                 0 if x else 1
-            """).stats[0]
+            """).stats.named('Foo')
         assert stats.score == 3
         assert stats.end_line == 5
 
             class Foo:
                 def foo():
                     0 if x else 1
-            """).stats[1].score == 2
+            """).stats.named('Foo.foo').score == 2
         assert complexity(
             """
             class Foo:
                 def foo():
                     0 if x else 1 if y else 2
-            """).stats[1].score == 3
+            """).stats.named('Foo.foo').score == 3
 
     def test_that_they_know_their_names(self):
         assert complexity(
             """
             class Foo:
                 def foo(): pass
-            """).stats[1].name == 'Foo.foo'
+            """).stats.named('Foo.foo').name == 'Foo.foo'
 
     def test_that_they_know_their_line_range(self):
         stats = complexity(
             class Foo():
                 def foo():
                     pass
-            """).stats[1]
+            """).stats.named('Foo.foo')
         assert stats.start_line == 3
         assert stats.end_line == 4
 
                 def foo():
                     pass
                     pass
-            """).stats[1]
+            """).stats.named('Foo.foo')
         assert stats.start_line == 4
         assert stats.end_line == 6