Add rendering test

This commit is contained in:
Jim Paris 2012-11-28 18:34:51 -05:00
parent 875fbe969f
commit 66fa6f3824
2 changed files with 109 additions and 3 deletions

73
tests/renderdot.py Normal file
View File

@ -0,0 +1,73 @@
import sys
class Renderer(object):
def __init__(self, getleft, getright,
getred, getstart, getend, nil):
self.getleft = getleft
self.getright = getright
self.getred = getred
self.getstart = getstart
self.getend = getend
self.nil = nil
# Rendering
def __render_dot_node(self, node, max_depth = 20):
from nilmdb.printf import sprintf
"""Render a single node and its children into a dot graph fragment"""
if max_depth == 0:
return ""
if node is self.nil:
return ""
def c(red):
if red:
return 'color="#ff0000", style=filled, fillcolor="#ffc0c0"'
else:
return 'color="#000000", style=filled, fillcolor="#c0c0c0"'
s = sprintf("%d [label=\"%g\\n%g\", %s];\n",
id(node),
self.getstart(node), self.getend(node),
c(self.getred(node)))
if self.getleft(node) is self.nil:
s += sprintf("L%d [label=\"-\", %s];\n", id(node), c(False))
s += sprintf("%d -> L%d [label=L];\n", id(node), id(node))
else:
s += sprintf("%d -> %d [label=L];\n",
id(node),id(self.getleft(node)))
if self.getright(node) is self.nil:
s += sprintf("R%d [label=\"-\", %s];\n", id(node), c(False))
s += sprintf("%d -> R%d [label=R];\n", id(node), id(node))
else:
s += sprintf("%d -> %d [label=R];\n",
id(node), id(self.getright(node)))
s += self.__render_dot_node(self.getleft(node), max_depth-1)
s += self.__render_dot_node(self.getright(node), max_depth-1)
return s
def render_dot(self, rootnode, title = "Tree"):
"""Render the entire tree as a dot graph"""
return ("digraph rbtree {\n"
+ self.__render_dot_node(rootnode)
+ "}\n");
def render_dot_live(self, rootnode, title = "Tree"):
"""Render the entiretree as a dot graph, live GTK view"""
import gtk
import gtk.gdk
sys.path.append("/usr/share/xdot")
import xdot
xdot.Pen.highlighted = lambda pen: pen
s = ("digraph rbtree {\n"
+ self.__render_dot_node(rootnode)
+ "}\n");
window = xdot.DotWindow()
window.set_dotcode(s)
window.set_title(title + " - any key to close")
window.connect('destroy', gtk.main_quit)
def quit(widget, event):
if not event.is_modifier:
window.destroy()
gtk.main_quit()
window.widget.connect('key-press-event', quit)
gtk.main()

View File

@ -270,6 +270,7 @@ class TestIntervalDB:
class TestIntervalTree: class TestIntervalTree:
def test_interval_tree(self): def test_interval_tree(self):
import renderdot
import random import random
random.seed(1234) random.seed(1234)
@ -280,6 +281,15 @@ class TestIntervalTree:
interval = Interval(i, i+1) interval = Interval(i, i+1)
iset += interval iset += interval
# Plot it
r = renderdot.Renderer(lambda node: node.cleft,
lambda node: node.cright,
lambda node: False,
lambda node: node.start,
lambda node: node.end,
iset.tree.emptynode())
r.render_dot_live(iset.tree.rootnode(), "Random insertion")
# remove about half of them # remove about half of them
for i in random.sample(xrange(j),j): for i in random.sample(xrange(j),j):
if random.randint(0,1): if random.randint(0,1):
@ -289,9 +299,32 @@ class TestIntervalTree:
with assert_raises(IntervalError): with assert_raises(IntervalError):
iset -= Interval(1234,5678) iset -= Interval(1234,5678)
# show the graph # Plot it
if False: r = renderdot.Renderer(lambda node: node.cleft,
iset.tree.render_dot_live() lambda node: node.cright,
lambda node: False,
lambda node: node.start,
lambda node: node.end,
iset.tree.emptynode())
r.render_dot_live(iset.tree.rootnode(), "Random insertion, deletion")
# make a set of 500 intervals, inserted in order
iset = IntervalSet()
j = 500
for i in xrange(j):
interval = Interval(i, i+1)
iset += interval
# Plot it
r = renderdot.Renderer(lambda node: node.cleft,
lambda node: node.cright,
lambda node: False,
lambda node: node.start,
lambda node: node.end,
iset.tree.emptynode())
r.render_dot_live(iset.tree.rootnode(), "In-order insertion")
assert(False)
class TestIntervalSpeed: class TestIntervalSpeed:
@unittest.skip("this is slow") @unittest.skip("this is slow")