Commits

Devin Jeanpierre committed 3f91b88

User-input parsing written

Comments (0)

Files changed (2)

doctest2/interactive.py

+import sys
+
 class ExamplePatcher:
     """
     Stateful class for patching the expected output of examples to say
         end_lineno = start_lineno + len(ex.want.splitlines())
         
         return (start_lineno, end_lineno) 
+
+class ParseFailure(Exception): pass
+
+def parse_change(header, edited, warning_out=sys.stderr.write):
+    """
+    Parse the changed footer out of an edited file that contained the header.
+    
+    Some safety checks are done to check whether the file was edited "correctly"
+    """
+    
+    if edited.startswith(header):
+        return edited[len(header):]
+    else:
+        warning_out("warning: parse_change: header was altered.")
+        header_divider = header.splitlines()[-1] + '\n'
+        try:
+            last_header_line = edited.rindex(header_divider)
+        except ValueError:
+            raise ParseFailure("Could not find where header ends")
+        else:
+            return edited[last_header_line + len(header_divider):]

doctest2/tests/test_interactive.py

         self.assertEqual(self.patcher.offsets, [(1, 1), (3, 1)])
         self.assertEqual(self.patcher.source[3:5], ["hee\n", "hee\n"])
 
+class TestParseChange(unittest.TestCase):
+    def setUp(self):
+        self.warnings = []
+        self.warnings_out = self.warnings.append
+    
+    def testWhenStartsWith(self):
+        self.assertEqual(
+            interactive.parse_change('hello\n', 'hello\nworld', self.warnings_out),
+            'world')
+        
+        self.assertEqual(self.warnings, [])
+    
+    def testWhenNotStartsWith(self):
+        self.assertEqual(
+            interactive.parse_change('hello\n', 'hihi\nhello\nworld', self.warnings_out),
+            'world')
+        
+        self.assertEqual(self.warnings,
+            ["warning: parse_change: header was altered."])
+    
+    def testWhenNotStartsWithPartialLine(self):
+        """
+        This is just to show that we're expecting this behavior: if you prefix
+        the terminating line with some stuff, it still reads fine.
+        """
+        
+        self.assertEqual(
+            interactive.parse_change('hello\n', 'shello\nworld', self.warnings_out),
+            'world')
+        
+        self.assertEqual(self.warnings,
+            ["warning: parse_change: header was altered."])
+    
+    
+    def testMatchFailure(self):
+        self.assertRaises(interactive.ParseFailure,
+            interactive.parse_change,'hello\n', 'ehllo\nworld', self.warnings_out)
+        
+        self.assertEqual(self.warnings,
+            ["warning: parse_change: header was altered."])
+
 if __name__ == '__main__':
     unittest.main()