# Calendaring is a simple CMF/Plone calendaring implementation. # Copyright (C) 2004 Enfold Systems # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Some portions of this module are Copyright Shuttleworth Foundation. # The original copyright statement is reproduced below. # # SchoolTool - common information systems platform for school administration # Copyright (c) 2003 Shuttleworth Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Common utilities (stubs, mixins) for schooltool unit tests. $Id: utils.py,v 1.2 2004/09/17 13:58:26 dreamcatcher Exp $ """ import sys import unittest from pprint import pformat from Products.Calendaring.tests.helpers import normalize_xml, diff __metaclass__ = type class EqualsSortedMixin: """Mixin that adds a helper method for comparing lists ignoring order.""" def assertEqualsSorted(self, a, b): x = list(a) y = list(b) x.sort() y.sort() self.assertEquals(x, y) assertEqualSorted = assertEqualsSorted class NiceDiffsMixin: """Mixin that changes assertEquals to show a unified diff of pretty-printed values. """ def assertEquals(self, results, expected, msg=None): if msg is None: msg = "\n" + diff(pformat(expected), pformat(results)) unittest.TestCase.assertEquals(self, results, expected, msg) assertEqual = assertEquals class XMLCompareMixin: def assertEqualsXML(self, result, expected, recursively_sort=()): """Assert that two XML documents are equivalent. If recursively_sort is given, it is a sequence of tags that will have test:sort="recursively" appended to their attribute lists in 'result' text. See the docstring for normalize_xml for more information about this attribute. """ result = normalize_xml(result, recursively_sort=recursively_sort) expected = normalize_xml(expected, recursively_sort=recursively_sort) self.assertEquals(result, expected, "\n" + diff(expected, result)) assertEqualXML = assertEqualsXML class QuietLibxml2Mixin: """Text mixin that disables libxml2 error reporting. Sadly the API of libxml2 does not allow us to restore the error reporting function in tearDown. """ def setUpLibxml2(self): import libxml2 libxml2.registerErrorHandler(lambda ctx, error: None, None) def tearDownLibxml2(self): import libxml2 # It's not possible to restore the error handler that was installed # before (libxml2 API limitation), so we set up a generic one that # prints everything to stdout. def on_error_callback(ctx, msg): sys.stderr.write(msg) libxml2.registerErrorHandler(on_error_callback, None) from Products.CMFCore.utils import getToolByName from Products.Archetypes.ArchetypeTool import FactoryTypeInformation from Products.Archetypes.ArchetypeTool import fixActionsForType, getType # Mostly copied from ArchetypeTool.manage_installType def installType(self, typeName, package, portal_type=None, ignore_actions=False): typesTool = getToolByName(self, 'portal_types') typeinfo_name="%s: %s" % (package, typeName) typeDesc = getType(typeName, package) if not portal_type: portal_type = typeDesc['portal_type'] try: typesTool._delObject(portal_type) except: pass typesTool.manage_addTypeInformation( FactoryTypeInformation.meta_type, id=portal_type, typeinfo_name=typeinfo_name) t = getattr(typesTool, typeName, None) if t: t.title = getattr(typeDesc['klass'], 'archetype_name', portal_type) if not ignore_actions: # and update the actions as needed fixActionsForType(typeDesc['klass'], typesTool)