Commit 41b83a75 authored by Martijn Pieters's avatar Martijn Pieters

- Additional methods on TreeMaker to set various aspects on how the tree is

  built. This allows PythonScripts to change attributes previously
  unaccessible because they start with an underscore.

- Add a test suite for the Tree.py module.
parent 5cccb2a2
......@@ -12,8 +12,8 @@
##############################################################################
__doc__='''Tree manipulation classes
$Id: Tree.py,v 1.10 2002/10/04 16:50:58 mj Exp $'''
__version__='$Revision: 1.10 $'[11:-2]
$Id: Tree.py,v 1.11 2002/10/04 20:06:52 mj Exp $'''
__version__='$Revision: 1.11 $'[11:-2]
from Acquisition import Explicit
from ComputedAttribute import ComputedAttribute
......@@ -83,6 +83,43 @@ class TreeMaker:
else:
self._values_function = function
def setIdAttr(self, id):
"""Set the attribute or method name called to get a unique Id.
The id attribute or method is used to get a unique id for every node in
the tree, so that the state of the tree can be encoded as a string using
Tree.encodeExpansion(). The returned id should be unique and stable
across Zope requests.
If the attribute or method isn't found on an object, either the objects
persistence Id or the result of id() on the object is used instead.
"""
self._id = id
def setExpandRoot(self, expand):
"""Set wether or not to expand the root node by default.
When no expanded flag or mapping is passed to .tree(), assume the root
node is expanded, and leave all subnodes closed.
The default is to expand the root node.
"""
self._expand_root = expand and True or False
def setAssumeChildren(self, assume):
"""Set wether or not to assume nodes have children.
When a node is not expanded, when assume children is set, don't
determine if it is a leaf node, but assume it can be opened. Use this
when determining the children for a node is expensive.
The default is to not assume there are children.
"""
self._assume_children = assume and True or False
def tree(self, root, expanded=None, subtree=0):
'''Create a tree from root, with specified nodes expanded.
......
import unittest
from ZTUtils import Tree
class Item:
children = ()
id = ''
def __init__(self, id, children=()):
self.id = id
self.children = children
def tpId(self): return self.id
def tpValues(self): return self.children
class TreeTests(unittest.TestCase):
def setUp(self):
self.tm = Tree.TreeMaker()
self.root = Item('a', (
Item('b', (
Item('d'), Item('e'))),
Item('c', (
Item('f', (
Item('h'), Item('i'))),
Item('g')))))
self.items = {
'a': self.root,
'b': self.root.children[0],
'c': self.root.children[1],
'd': self.root.children[0].children[0],
'e': self.root.children[0].children[1],
'f': self.root.children[1].children[0],
'g': self.root.children[1].children[1],
'h': self.root.children[1].children[0].children[0],
'i': self.root.children[1].children[0].children[1],
}
self.expansionmap = {Tree.b2a('a'): {Tree.b2a('c'): None}}
def testBaseTree(self):
treeroot = self.tm.tree(self.root)
self.assertEqual(len(treeroot), 2)
self.assertEqual(treeroot.size, 3)
self.assertEqual(treeroot.height, 2)
self.assertEqual(treeroot.depth, 0)
self.assertEqual(treeroot.state, 1)
self.assert_(treeroot.object is self.root)
i = 'b'
for subnode in treeroot:
self.assertEqual(len(subnode), 0)
self.assertEqual(subnode.size, 1)
self.assertEqual(subnode.height, 1)
self.assertEqual(subnode.depth, 1)
self.assertEqual(subnode.state, -1)
self.assert_(subnode.object is self.items[i])
i = chr(ord(i) + 1)
expected_set = [self.items['a'], self.items['b'], self.items['c']]
set = treeroot.flat()
self.assertEqual(len(set), treeroot.size)
self.assertEqual([s.object for s in set], expected_set)
set = []
def collect(node, set=set): set.append(node.object)
treeroot.walk(collect)
self.assertEqual(len(set), treeroot.size)
self.assertEqual(set, expected_set)
def testExpandedTree(self):
treeroot = self.tm.tree(self.root, 1)
self.assertEqual(len(treeroot), 2)
self.assertEqual(treeroot.size, len(self.items))
self.assertEqual(treeroot.height, 4)
self.assertEqual(treeroot.depth, 0)
self.assertEqual(treeroot.state, 1)
self.assert_(treeroot.object is self.root)
items = self.items
expected_set = [items['a'], items['b'], items['d'], items['e'],
items['c'], items['f'], items['h'], items['i'], items['g']]
set = treeroot.flat()
self.assertEqual(len(set), treeroot.size)
self.assertEqual([s.object for s in set], expected_set)
set = []
def collect(node, set=set): set.append(node.object)
treeroot.walk(collect)
self.assertEqual(len(set), treeroot.size)
self.assertEqual(set, expected_set)
leaves = ('d', 'e', 'g', 'h', 'i')
for node in treeroot.flat():
if node.object.id in leaves:
self.assertEqual(node.state, 0)
else:
self.assertEqual(node.state, 1)
self.assertEqual(node.size, len(node.flat()))
def testExpandsionMap(self):
treeroot = self.tm.tree(self.root, self.expansionmap)
self.assertEqual(treeroot.size, 5)
self.assertEqual(treeroot.state, 1)
self.assertEqual(treeroot[0].state, -1)
self.assertEqual(treeroot[1].state, 1)
self.assertEqual(treeroot[1][0].state, -1)
self.assertEqual(treeroot[1][1].state, 0)
def testAssumeChildren(self):
self.tm.setAssumeChildren(True)
treeroot = self.tm.tree(self.root, self.expansionmap)
self.assertEqual(treeroot[1][1].state, -1)
def testNoExpandRoot(self):
self.tm.setExpandRoot(False)
treeroot = self.tm.tree(self.root)
self.assertEqual(treeroot.state, -1)
self.assertEqual(len(treeroot), 0)
def testIdAttribute(self):
treeroot = self.tm.tree(self.root)
self.tm.setIdAttr('id')
treeroot2 = self.tm.tree(self.root)
self.assertEqual(treeroot.id, treeroot2.id)
def testChildrenAttribute(self):
self.tm.setChildAccess(attrname='children')
treeroot = self.tm.tree(self.root)
self.assertEqual(len(treeroot), 2)
def testChildrenFilter(self):
def filter(children):
return [c for c in children if c.id in ('b', 'd')]
self.tm.setChildAccess(filter=filter)
treeroot = self.tm.tree(self.root, 1)
self.assertEqual(treeroot.size, 3)
self.assertEqual(len(treeroot), 1)
self.assertEqual(len(treeroot[0]), 1)
expected_set = [self.items['a'], self.items['b'], self.items['d']]
set = []
def collect(node, set=set): set.append(node.object)
treeroot.walk(collect)
self.assertEqual(set, expected_set)
def testChildrenFunction(self):
def childrenFunction(object):
return object.children
self.tm.setChildAccess(function=childrenFunction)
treeroot = self.tm.tree(self.root)
self.assertEqual(len(treeroot), 2)
def testEncodeDecode(self):
treeroot1 = self.tm.tree(self.root, self.expansionmap)
encoded = Tree.encodeExpansion(treeroot1.flat())
decodedmap = Tree.decodeExpansion(encoded)
treeroot2 = self.tm.tree(self.root, decodedmap)
self.assertEqual(treeroot1.size, treeroot2.size)
self.assertEqual(len(treeroot1), len(treeroot2))
def test_suite():
return unittest.makeSuite(TreeTests)
if __name__=='__main__':
unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment