[TIP] figleaf tests

Ondrej Certik ondrej at certik.cz
Mon Jun 23 16:43:40 PDT 2008


Hi,

I think we need tests in a form of code snippets and corresponding
numbers of all lines that can be executed and this will be checked
against the LineGrabber class.

Below is an email I sent to Titus -- I think it's better to discuss it
here on the mailinglist, anyone feel free to discuss it.

Here is a one that doesn't work:

------
def msigma(i):
   if i==1:
       mat=( (
           (0, 1),
           (1, 0)
           ) )
   else:
       mat=( (
           (0, -1),
           (1, 0)
           ) )
   return mat

print msigma(1)
print msigma(2)
------

lines reported from LineGrabber:

set([1, 2, 3, 8, 12, 14, 15])

and covered lines:

set([1, 2, 4, 5, 9, 10, 12, 14, 15])

so you can see that instead of lines 3 and 8, the sys.trace returns
4,5 and 9,10.


I fixed the LineGrabber.find_terminal_nodes() to report the lines 4,5
and 9, 10 instead 3 and 8 for this particular case. Here is a patch
(it works, but probably could be made nicer):

diff --git a/figleaf/internals.py b/figleaf/internals.py
--- a/figleaf/internals.py
+++ b/figleaf/internals.py
@@ -60,12 +60,19 @@ class LineGrabber:
            for x in rest:
                token_line_no = self.find_terminal_nodes(x)
                if token_line_no is not None:
-                    line_nos.add(token_line_no)
+                    for y in token_line_no:
+                        line_nos.add(y)

            if symbol.sym_name[sym] in ('stmt', 'suite', 'lambdef',
                                        'except_clause') and line_nos:
                # store the line number that this statement started at
-                self.lines.add(min(line_nos))
+                if len(line_nos) in [1, 2]:
+                    self.lines.add(min(line_nos))
+                else:
+                    for y in line_nos:
+                        self.lines.add(y)
+                    self.lines.remove(min(line_nos))
+                    self.lines.remove(max(line_nos))
            elif symbol.sym_name[sym] in ('if_stmt',):
                # add all lines under this
                self.lines.update(line_nos)
@@ -73,12 +80,12 @@ class LineGrabber:
                return
            else:
                if line_nos:
-                    return min(line_nos)
+                    return line_nos

        else:                               ### leaf
            if sym not in (NEWLINE, STRING, INDENT, DEDENT, COLON) and \
               tup[1] != 'else':
-                return tup[2]
+                return [tup[2]]
            return None

    def pretty_print(self, tup=None, indent=0):



This gives the idea what needs to be fixed and how. Now however, this
patch probably breaks some other code.

I think we should first do the tests I propose above, then you can
commit this patch with a test
without worrying of breaking something. Or if you have some better
strategy, let me know.


Ondrej



More information about the testing-in-python mailing list