Commits

desmaj committed 534463f

added 'pragma: no cond'

Comments (0)

Files changed (6)

instrumental/constructs.py

 
 class LogicalBoolean(object):
     
-    def __init__(self, modulename, node, parent):
+    def __init__(self, modulename, node, parent=None):
         self.modulename = modulename
         self.node = deepcopy(node)
         self.lineno = node.lineno

instrumental/pragmas.py

 
 from astkit import ast
 
-class PragmaNoCover(object):
-    block = True
+class Pragma(object):
+    block = False
     
     def __init__(self, match):
         pass
 
-class PragmaNoCondition(object):
+    def __call__(self, construct):
+        return ConstructWrapper(construct, self)
+    
+    def apply(self, construct):
+        return construct
+
+class PragmaNoCover(Pragma):
+    block = True
+    
+class PragmaNoCondition(Pragma):
     block = False
     
     def __init__(self, match):
         self.conditions = match.group(1).split(',')
         
+    def __call__(self, construct):
+        return ConstructWrapper(construct, self)
+    
+    def apply(self, construct):
+        for condition in construct.conditions:
+            if construct.description(condition) in self.conditions:
+                construct.conditions[condition] = True
+        return construct
+
+class ConstructWrapper(object):
+    
+    def __init__(self, construct, pragma):
+        self.construct = pragma.apply(construct)
+    
+    def __getattr__(self, attr):
+        if hasattr(self.construct, attr):
+            return getattr(self.construct, attr)
+        raise AttributeError(attr)
+
 valid_pragmas = {
     r'no\s+cover': PragmaNoCover,
-    r'no\s+cond\(([TF](\s+[TF])*(,[TF](\s+[TF]))*)\)': PragmaNoCondition,
+    r'no\s+cond\(([TF\*](\s+[TF\*])*(,[TF\*](\s+[TF\*]))*)\)': PragmaNoCondition,
     }
 
 class PragmaApplier(ast.NodeVisitor):

instrumental/recorder.py

         else:
             raise TypeError("Expected a BoolOp node with an op field of ast.And or ast.Or")
         construct = construct_klass(modulename, node, parent)
+        for pragma in pragmas:
+            construct = pragma(construct)
         
         label = self.next_label()
         self._constructs[label] = construct

instrumental/test/samples/pragmas/__init__.py

Empty file added.

instrumental/test/samples/pragmas/simple.py

+
+def test_func(emitt):    
+    flag_1 = False
+    if flag_1: # pragma: no cond(T)
+        emit('flag_1 T')
+    
+    for flag_2 in [True, False]:
+        if flag_2 and flag_1: # pragma: no cond(T T,F T)
+            emit('flag_2 and flag_1 T T')

instrumental/test/test_pragmas.py

+class TestPragmaFinder(object):
+    
+    def setup(self):
+        from instrumental.pragmas import PragmaFinder
+        self.finder = PragmaFinder()
+    
+    def test_pragma_no_cover(self):
+        from instrumental.pragmas import PragmaNoCover
+        source = """
+acc = 1
+acc += 2
+if add_three:
+    acc += 3 # pragma: no cover
+acc += 4
+"""
+        pragmas = self.finder.find_pragmas(source)
+        assert 6 == len(pragmas), pragmas
+        assert not pragmas[1]
+        assert not pragmas[2]
+        assert not pragmas[3]
+        assert not pragmas[4]
+        assert pragmas[5], pragmas
+        assert isinstance(list(pragmas[5])[0], PragmaNoCover)
+        assert not pragmas[6]
+    
+    def test_pragma_no_cond_T(self):
+        from instrumental.pragmas import PragmaNoCondition
+        source = """
+acc = 1
+acc += 2
+if add_three: # pragma: no cond(T)
+    acc += 3
+acc += 4
+"""
+        pragmas = self.finder.find_pragmas(source)
+        assert 6 == len(pragmas), pragmas
+        assert not pragmas[1]
+        assert not pragmas[2]
+        assert not pragmas[3]
+        assert 1 == len(pragmas[4])
+        pragma_4 = list(pragmas[4])[0]
+        assert isinstance(pragma_4, PragmaNoCondition)
+        assert pragma_4.conditions == ['T']
+        assert not pragmas[5]
+        assert not pragmas[6]
+
+    def test_pragma_no_cond_T_F(self):
+        from instrumental.pragmas import PragmaNoCondition
+        source = """
+acc = 1
+acc += 2
+if add_three and add_four: # pragma: no cond(T F)
+    acc += 3
+acc += 4
+"""
+        pragmas = self.finder.find_pragmas(source)
+        assert 6 == len(pragmas), pragmas
+        assert not pragmas[1]
+        assert not pragmas[2]
+        assert not pragmas[3]
+        assert 1 == len(pragmas[4])
+        pragma_4 = list(pragmas[4])[0]
+        assert isinstance(pragma_4, PragmaNoCondition)
+        assert pragma_4.conditions == ['T F']
+        assert not pragmas[5]
+        assert not pragmas[6]
+
+    def test_pragma_no_cond_multiple_conditions(self):
+        from instrumental.pragmas import PragmaNoCondition
+        source = """
+acc = 1
+acc += 2
+if add_three and add_four: # pragma: no cond(T F,F T)
+    acc += 3
+acc += 4
+"""
+        pragmas = self.finder.find_pragmas(source)
+        assert 6 == len(pragmas), pragmas
+        assert not pragmas[1]
+        assert not pragmas[2]
+        assert not pragmas[3]
+        assert 1 == len(pragmas[4])
+        pragma_4 = list(pragmas[4])[0]
+        assert isinstance(pragma_4, PragmaNoCondition)
+        assert sorted(pragma_4.conditions) == ['F T', 'T F']
+        assert not pragmas[5]
+        assert not pragmas[6]
+
+class TestPragmaNoCondition(object):
+    
+    def test_conditions_are_ignored(self):
+        import re
+        from astkit import ast
+        from instrumental.constructs import LogicalAnd
+        from instrumental.pragmas import PragmaNoCondition
+        node = ast.BoolOp(values=[ast.Name(id="x"), ast.Name(id="y")],
+                          op=ast.And(),
+                          lineno=17,
+                          col_offset=4)
+        construct = LogicalAnd('<string>', node, None)
+        match = re.match(r'(T F,F \*)', 'T F,F *')
+        pragma = PragmaNoCondition(match)
+        construct = pragma(construct)
+        assert '(x and y)' == construct.source
+        assert 3 == construct.number_of_conditions()
+        assert "T T" == construct.description(0)
+        assert "F *" == construct.description(1)
+        assert "T F" == construct.description(2)
+        
+        # T T
+        construct.record(True, 0)
+        construct.record(True, 1)
+        
+        print construct.conditions
+        assert not construct.conditions_missed()