You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@gump.apache.org by le...@apache.org on 2005/04/18 21:16:20 UTC
svn commit: r161784 - in gump/branches/Gump3/pygump/python/gump:
engine/modeller.py test/testModeller.py
Author: leosimons
Date: Mon Apr 18 12:16:19 2005
New Revision: 161784
URL: http://svn.apache.org/viewcvs?view=rev&rev=161784
Log:
Start testing Loader and solidifying it a little.
* pygump/python/gump/engine/modeller.py: add in (untested so far, unfortunately) code to prevent recursive hrefs (GUMP-38), and do argument checking on the stuff provided to __init__.
* pygump/python/gump/test/testModeller.py: start with basic unit tests for the Loader class (GUMP-91).
Modified:
gump/branches/Gump3/pygump/python/gump/engine/modeller.py
gump/branches/Gump3/pygump/python/gump/test/testModeller.py
Modified: gump/branches/Gump3/pygump/python/gump/engine/modeller.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/engine/modeller.py?view=diff&r1=161783&r2=161784
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/engine/modeller.py (original)
+++ gump/branches/Gump3/pygump/python/gump/engine/modeller.py Mon Apr 18 12:16:19 2005
@@ -202,6 +202,11 @@
be None only if the workspace to load does not contain
any hrefs.
"""
+ assert hasattr(log, "warning")
+ assert callable(log.warning)
+ if vfs:
+ assert hasattr(vfs, "get_as_stream")
+ assert callable(vfs.get_as_stream)
self.log = log
self.vfs = vfs
@@ -228,9 +233,10 @@
def _resolve_hrefs_in_workspace(self, ws, dropped_nodes):
"""Redirects to _resolve_hrefs_in_children."""
- self._resolve_hrefs_in_children(ws, dropped_nodes)
+ found_hrefs=[]
+ self._resolve_hrefs_in_children(ws, dropped_nodes, found_hrefs)
- def _resolve_hrefs_in_children(self, element, dropped_nodes):
+ def _resolve_hrefs_in_children(self, element, dropped_nodes, found_hrefs):
"""Recursively resolve all hrefs in all the children for a DOM node.
The resolution is done in a resolve-then-recurse manner, so the end
@@ -238,8 +244,12 @@
be passed in a dom Element or something else which actually has children;
passing in an Attr for example makes no sense and results in problems.
- The dropped_nodes arguments should be a list that will be populated with
+ The dropped_nodes argument should be a list that will be populated with
nodes for which href resolution fails.
+
+ The found_hrefs argument should be al ist that will be populated with all
+ the hrefs that have been resolved by the method that resolved hrefs for
+ the parent. An error will be thrown when recursion is detected.
"""
for child in element.childNodes:
# only resolve hrefs for elements
@@ -252,12 +262,15 @@
self._resolve_href(child, dropped_nodes)
# now recurse to resolve any hrefs within this child
- self._resolve_hrefs_in_children(child, dropped_nodes)
+ # note that we duplicate the found_hrefs array. This means that the
+ # same file can be imported multiple times, as long as it is imported
+ # by siblings, rather than as part of some parent<->child relation.
+ self._resolve_hrefs_in_children(child, dropped_nodes, found_hrefs[:])
# we're now done with resolution
#return node
- def _resolve_href(self, node, dropped_nodes):
+ def _resolve_href(self, node, dropped_nodes, found_hrefs):
"""Resolve a href for the provided node.
We merge in the referenced xml document into the provided node.
@@ -266,7 +279,12 @@
its parent and appended to the dropped_nodes list.
"""
href = node.getAttribute('href')
+ if href in found_hrefs:
+ raise ModellerError, \
+"""Recursive inclusion because files refer to each other. This href leads to
+a cycle: %s.""" % href
self.log.debug( "Resolving HREF: %s" % href )
+ found_hrefs.append(href)
try:
stream = self.vfs.get_as_stream(href)
Modified: gump/branches/Gump3/pygump/python/gump/test/testModeller.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/test/testModeller.py?view=diff&r1=161783&r2=161784
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/test/testModeller.py (original)
+++ gump/branches/Gump3/pygump/python/gump/test/testModeller.py Mon Apr 18 12:16:19 2005
@@ -21,6 +21,7 @@
from unittest import TestCase
from xml.dom import minidom
+import StringIO
from gump.engine.modeller import _find_element_text
from gump.engine.modeller import _do_drop
@@ -30,6 +31,8 @@
from gump.engine.modeller import _find_module_containing_node
from gump.engine.modeller import _find_project_containing_node
from gump.engine.modeller import _import_node
+from gump.engine.modeller import ModellerError
+from gump.engine.modeller import Loader
class ModellerTestCase(TestCase):
def setUp(self):
@@ -83,6 +86,20 @@
"""
self.sampledom2 = minidom.parseString(self.samplexml2)
+ self.sampleworkspacestring = """<?xml version="1.0"?>
+
+<workspace>
+ <newelem attr="yo">contents</newelem>
+ <module name="foo">
+ <project name="bar">
+ <blah/>
+ </project>
+ </module>
+ <newelem>ignore</newelem>
+</workspace>
+"""
+ self.sampleworkspace = minidom.parseString(self.sampleworkspacestring)
+
def test_find_element_text(self):
root = self.sampledom.documentElement
text = _find_element_text(root, "elem")
@@ -158,6 +175,49 @@
self.assertEqual(1, oldroot.getElementsByTagName("uniquetaghere").length)
self.assertEqual(2, oldroot.getElementsByTagName("newelem").length)
self.assertEqual(1, oldroot.getElementsByTagName("newstuff").length)
+
+ def test_modeller_error(self):
+ error = ModellerError()
+ self.assert_(isinstance(error, Exception))
+
+ def test_loader_init(self):
+ log = MockLog()
+ vfs = MockVFS()
+
+ loader = Loader(log,vfs)
+ loader = Loader(log,None)
+
+ self.assertRaises(AssertionError, Loader, self, vfs)
+ self.assertRaises(AssertionError, Loader, log, self)
+ self.assertRaises(AssertionError, Loader, None, vfs)
+
+ def test_loader_get_workspace_tree_simple(self):
+ log = MockLog()
+ vfs = MockVFS()
+ loader = Loader(log,vfs)
+
+ (wsdom, dropped_nodes) = loader.get_workspace_tree(StringIO.StringIO(self.sampleworkspacestring))
+ # TODO check wsdom content validity
+ self.assertEqual(0, len(dropped_nodes))
+ self.assertEqual(type(self.sampleworkspace), type(wsdom))
+ self.assertEqual(None, log.msg)
+ self.assertEqual(None, vfs.href)
+
+ # TODO test loader href resolution
+ # TODO test loader looping href resolution
+ # TODO test loader href resolution failure
+ # TODO test loader vfs exception
+
+class MockLog:
+ msg = None
+ def warning(self,msg):
+ self.msg = msg
+
+class MockVFS:
+ href = None
+ def get_as_stream(href):
+ self.href = href
+ return StringIO.StringIO()
# this is used by testrunner.py to determine what tests to run
def test_suite():