[pypy-svn] r5194 - pypy/trunk/src/pypy/tool

lac at codespeak.net lac at codespeak.net
Mon Jun 21 14:43:53 CEST 2004


Author: lac
Date: Mon Jun 21 14:43:53 2004
New Revision: 5194

Added:
   pypy/trunk/src/pypy/tool/utestconvert.py
Log:
bring this one over here before I go to work so I don't have to
check out the branch to get at thisone file.


Added: pypy/trunk/src/pypy/tool/utestconvert.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/tool/utestconvert.py	Mon Jun 21 14:43:53 2004
@@ -0,0 +1,450 @@
+import re
+import unittest
+import parser
+import os
+
+d={}
+
+#  d is the dictionary of unittest changes, keyed to the old name
+#  used by unittest.  d['new'] is the new replacement function, and
+#  d['change'] is one of the following functions
+#           namechange_only   e.g.  assertRaises  becomes raises
+#           fail_special      e.g.  fail() becomes raise AssertionError
+#           strip_parens      e.g.  assert_(expr) becomes assert expr
+#           comma_to_op       e.g.  assertEquals(l, r) becomes assert l == r
+#           rounding          e.g.  assertAlmostEqual(l, r) becomes
+#                                   assert round(l - r, 7) == 0
+#  Finally, 'op' is the operator you will substitute, if applicable.
+#  Got to define the dispatch functions first ....
+
+def namechange_only(old, new, block, op):
+    '''rename a function.  dictionary dispatched.'''
+    return re.sub('self.'+old, new, block)
+
+def fail_special(old, new, block, op):
+    '''change fail function to raise AssertionError. dictionary dispatched. '''
+    indent, expr, trailer = common_setup(old, block)
+    
+    if expr == '':  # fail()  --> raise AssertionError
+         return indent + new + trailer
+    else:   # fail('Problem')  --> raise AssertionError, 'Problem'
+         return indent + new + ', ' + expr + trailer
+
+def comma_to_op(old, new, block, op):
+    '''change comma to appropriate op. dictionary dispatched. '''
+    indent, expr, trailer = common_setup(old, block)
+    new = new + ' '
+    op = ' ' + op
+    left, right = get_expr(expr, ',')
+
+    try:
+        parser.expr(left.lstrip())  # that paren came off easily
+    except SyntaxError:
+        left  = re.sub(linesep, '\\'+linesep, left)
+        
+    right = process_args(right)
+
+    if right.startswith(linesep):
+        op = op + '\\'
+
+    return indent + new + left + op + right + trailer
+ 
+def strip_parens(old, new, block, op):
+    '''remove one set of parens. dictionary dispatched. '''
+    indent, args, trailer = common_setup(old, block)
+    new = new + ' '
+
+    args = process_args(args)
+    return indent + new + args + trailer
+
+def rounding(old, new, block, op):
+    '''special for assertAlmostEqual and freinds. dictionary dispatched. '''
+    indent, args, trailer = common_setup(old, block)
+    op = ' ' + op + ' '
+
+    first, rest = get_expr(args.lstrip())
+    second, rest = find_first_expr(rest.lstrip())
+    try:
+        places, msg = find_first_expr(rest.lstrip())
+        if msg:
+            places = places.rstrip()[:-1]
+            return indent + new + '(' + first + ' - ' + second + ' ' + \
+                   places + ')' + op + '0,' + msg
+        else:
+            return indent + new + '(' + first + ' - ' + second + ' ' + \
+                   places + ')' + op + '0'
+
+    except AttributeError:
+        return indent + new + '(' + first + ' - ' + second + ', 7)' + op + '0'
+      
+# Now the dictionary of unittests.  There sure are enough of them!
+
+d['assertRaises'] = {'new': 'raises', 'change': namechange_only, 'op': None}
+d['failUnlessRaises'] = d['assertRaises']
+
+d['fail'] = {'new': 'raise AssertionError', 'change': fail_special, 'op': None}
+
+d['assertEqual'] = {'new': 'assert', 'change': comma_to_op, 'op': '=='}
+d['assertEquals'] = d['assertEqual']
+
+d['assertNotEqual'] = {'new': 'assert', 'change':comma_to_op, 'op': '!='}
+d['assertNotEquals'] = d['assertNotEqual']
+
+d['failUnlessEqual'] = {'new': 'assert not', 'change': comma_to_op, 'op': '!='}
+
+d['failIfEqual'] = {'new': 'assert not', 'change': comma_to_op, 'op': '=='}
+
+d['assert_'] = {'new': 'assert','change': strip_parens, 'op': None}
+d['failUnless'] = d['assert_']
+
+d['failIf'] = {'new': 'assert not', 'change': strip_parens, 'op': None}
+
+d['assertAlmostEqual'] = {'new': 'assert round', 'change': rounding, 'op':'=='}
+d['assertAlmostEquals'] = d['assertAlmostEqual']
+
+d['assertNotAlmostEqual'] = {'new':'assert round','change':rounding, 'op':'!='}
+d['assertNotAlmostEquals'] = d['assertNotAlmostEqual']
+
+d['failIfAlmostEqual'] = {'new': 'assert not round',
+                          'change': rounding, 'op': '=='}
+d['failUnlessAlmostEqual'] = {'new': 'assert not round',
+                               'change': rounding, 'op': '!='}
+
+leading_spaces = re.compile(r'^(\s*)') # this never fails
+
+pat = ''
+for k in d.keys():  # this complicated pattern to match all unittests
+    pat += '|' + r'^(\s*)' + 'self.' + k + r'\(' # \tself.whatever(
+
+old_names = re.compile(pat[1:])
+linesep=os.linesep
+
+def blocksplitter(filename):
+    '''split a file into blocks that are headed by functions to rename'''
+    fp = file(filename, 'r')
+    blocklist = []
+    blockstring = ''
+
+    for line in fp:
+        interesting = old_names.match(line)
+        if interesting :
+            if blockstring:
+                blocklist.append(blockstring)
+                blockstring = line # reset the block
+        else:
+            blockstring += line
+            
+    blocklist.append(blockstring)
+    return blocklist
+
+def dispatch(s):
+    '''do a dictionary dispatch based on the change key in the dict d '''
+    f = old_names.match(s)
+    if f:
+        key = f.group(0).lstrip()[5:-1]  # '\tself.blah(' -> 'blah'
+        return d[key]['change'](key, d[key]['new'], s, d[key] ['op'])
+    else: # just copy uninteresting lines
+        return s
+
+def common_setup(old, block):
+    '''split the block into component parts'''
+    indent = re.search(r'^(\s*)', block).group()
+    pat = re.search('self.' + old + r'\(', block)
+    expr, trailer = get_expr(block[pat.end():], ')')
+    return indent, expr, trailer
+
+def find_first_expr(args):
+    '''find the first expression, return it, and the rest if it exists'''
+    sep = ','
+    try:
+        left, right = get_expr(args, sep)
+        left = re.sub(linesep, '\\'+linesep, left)
+
+        # only repair the lhs.  The rhs may be a multiline string that
+        # can take care of itself.
+            
+        if right.startswith(linesep):# that needs a slash too ...
+            sep = sep + '\\'
+        
+        return left + sep, right
+    except SyntaxError: # just a regular old multiline expression
+        return re.sub(linesep, '\\'+linesep, args), None
+
+def process_args(args):
+    '''start the process whereby lines that need backslashes get them'''
+    try:
+        parser.expr(args.lstrip()) # the parens come off easily
+        return args
+    except SyntaxError:
+        # paste continuation backslashes on our multiline constructs.
+        left, right = find_first_expr(args)
+        if right:
+            return left + right
+        else:
+            return left
+
+def get_expr(s, char=','):
+    '''split a string into an expression, and the rest of the string'''
+    pos=[]
+    for i in range(len(s)):
+        if s[i] == char:
+            pos.append(i)
+    if pos == []:
+        raise SyntaxError # we didn't find the expected char.  Ick.
+     
+    for p in pos:
+        # make the python parser do the hard work of deciding which comma
+        # splits the string into two expressions
+        try:
+            parser.expr('(' + s[:p] + ')')
+            return s[:p], s[p+1:]
+        except SyntaxError: # It's not an expression yet
+            pass
+    raise SyntaxError       # We never found anything that worked.
+
+class Testit(unittest.TestCase):
+    def test(self):
+        self.assertEquals(dispatch("badger badger badger"),
+                          "badger badger badger")
+
+        self.assertEquals(dispatch(
+            "self.assertRaises(excClass, callableObj, *args, **kwargs)"
+            ),
+            "raises(excClass, callableObj, *args, **kwargs)"
+                          )
+
+        self.assertEquals(dispatch(
+            """
+            self.failUnlessRaises(TypeError, func, 42, **{'arg1': 23})
+            """
+            ),
+            """
+            raises(TypeError, func, 42, **{'arg1': 23})
+            """
+                          )
+        self.assertEquals(dispatch(
+            """
+            self.assertRaises(TypeError,
+                              func,
+                              mushroom)
+            """
+            ),
+            """
+            raises(TypeError,
+                              func,
+                              mushroom)
+            """
+                          )
+        self.assertEquals(dispatch("self.fail()"), "raise AssertionError")
+        self.assertEquals(dispatch("self.fail('mushroom, mushroom')"),
+                          "raise AssertionError, 'mushroom, mushroom'")
+        self.assertEquals(dispatch("self.assert_(x)"), "assert x")
+        self.assertEquals(dispatch("self.failUnless(func(x)) # XXX"),
+                          "assert func(x) # XXX")
+        
+        self.assertEquals(dispatch(
+            """
+            self.assert_(1 + f(y)
+                         + z) # multiline, add continuation backslash
+            """
+            ),
+            r"""
+            assert 1 + f(y)\
+                         + z # multiline, add continuation backslash
+            """
+                          )
+
+        self.assertEquals(dispatch("self.assert_(0, 'badger badger')"),
+                          "assert 0, 'badger badger'")
+
+        self.assertEquals(dispatch(
+            r"""
+            self.assert_(0,
+                 'Meet the badger.\n')
+            """
+            ),
+            r"""
+            assert 0,\
+                 'Meet the badger.\n'
+            """
+                          )
+        
+        self.assertEquals(dispatch(
+            r"""
+            self.failIf(0 + 0
+                          + len('badger\n')
+                          + 0, '''badger badger badger badger
+                                 mushroom mushroom
+                                 Snake!  Ooh a snake!
+                              ''') # multiline, must remove the parens
+            """
+            ),
+            r"""
+            assert not 0 + 0\
+                          + len('badger\n')\
+                          + 0, '''badger badger badger badger
+                                 mushroom mushroom
+                                 Snake!  Ooh a snake!
+                              ''' # multiline, must remove the parens
+            """
+                          )
+
+        self.assertEquals(dispatch("self.assertEquals(0, 0)"),
+                          "assert 0 == 0")
+        
+        self.assertEquals(dispatch(
+            r"""
+            self.assertEquals(0,
+                 'Run away from the snake.\n')
+            """
+            ),
+            r"""
+            assert 0 ==\
+                 'Run away from the snake.\n'
+            """
+                          )
+
+        self.assertEquals(dispatch(
+            r"""
+            self.assertEquals(badger + 0
+                              + mushroom
+                              + snake, 0)
+            """
+            ),
+            r"""
+            assert badger + 0\
+                              + mushroom\
+                              + snake == 0
+            """
+                          )
+                            
+        self.assertEquals(dispatch(
+            r"""
+            self.assertNotEquals(badger + 0
+                              + mushroom
+                              + snake,
+                              mushroom
+                              - badger)
+            """
+            ),
+            r"""
+            assert badger + 0\
+                              + mushroom\
+                              + snake !=\
+                              mushroom\
+                              - badger
+            """
+                          )
+
+        self.assertEqual(dispatch(
+            r"""
+            self.assertEquals(badger(),
+                              mushroom()
+                              + snake(mushroom)
+                              - badger())
+            """
+            ),
+            r"""
+            assert badger() ==\
+                              mushroom()\
+                              + snake(mushroom)\
+                              - badger()
+            """
+                         )
+        self.assertEquals(dispatch("self.failIfEqual(0, 0)"),
+                          "assert not 0 == 0")
+
+        self.assertEquals(dispatch("self.failUnlessEqual(0, 0)"),
+                          "assert not 0 != 0")
+
+        self.assertEquals(dispatch(
+            r"""
+            self.failUnlessEqual(mushroom()
+                                 + mushroom()
+                                 + mushroom(), '''badger badger badger badger
+                                 badger badger badger badger
+                                 badger badger badger badger
+                                 ''') # multiline, must remove the parens
+            """
+            ),
+            r"""
+            assert not mushroom()\
+                                 + mushroom()\
+                                 + mushroom() != '''badger badger badger badger
+                                 badger badger badger badger
+                                 badger badger badger badger
+                                 ''' # multiline, must remove the parens
+            """
+                          )
+                              
+        self.assertEquals(dispatch(
+            r"""
+            self.assertEquals(badger(),
+                              snake(), 'BAD BADGER')
+            """
+            ),
+            r"""
+            assert badger() ==\
+                              snake(), 'BAD BADGER'
+            """
+                          )
+        self.assertEquals(dispatch(
+            r"""
+            self.assertEquals(badger(),
+                              snake(), '''BAD BADGER
+                              BAD BADGER
+                              BAD BADGER'''
+                              )
+            """
+            ),
+            r"""
+            assert badger() ==\
+                              snake(), '''BAD BADGER
+                              BAD BADGER
+                              BAD BADGER'''
+                              
+            """
+                          )
+        self.assertEquals(dispatch(
+            r"""
+            self.assertNotEquals(badger(),
+                              snake()+
+                              snake(), 'POISONOUS MUSHROOM!\
+                              Ai! I ate a POISONOUS MUSHROOM!!')
+            """
+            ),
+            r"""
+            assert badger() !=\
+                              snake()+\
+                              snake(), 'POISONOUS MUSHROOM!\
+                              Ai! I ate a POISONOUS MUSHROOM!!'
+            """
+                          )
+        self.assertEquals(dispatch("self.assertAlmostEqual(f, s, 4, 'ow')"),
+            "assert round(f - s, 4) == 0, 'ow'"
+                          )
+        self.assertEquals(dispatch("self.assertAlmostEquals(b, m, 200)"),
+            "assert round(b - m, 200) == 0"
+                          )
+        self.assertEquals(dispatch("self.failUnlessAlmostEqual(l, q)"),
+            "assert not round(l - q, 7) != 0"
+                          )
+        self.assertEquals(dispatch(
+            r"""
+            self.failIfAlmostEqual(badger(),
+                                   snake(),
+                                   6, 'POISONOUS SNAKE!\
+                                   Ai! I was bit by a POISONOUS SNAKE!!')
+            """
+            ),
+            r"""
+            assert not round(badger() - snake(),\
+                                   6) == 0, 'POISONOUS SNAKE!\
+                                   Ai! I was bit by a POISONOUS SNAKE!!'
+            """
+            )
+
+if __name__ == '__main__':
+    unittest.main()
+    #for block in  blocksplitter('xxx.py'): print dispatch(block)
+



More information about the Pypy-commit mailing list