[Checkins] SVN: zope.configuration/branches/tseaver-test_cleanup/ Prep for coverage.
Tres Seaver
cvs-admin at zope.org
Tue May 8 01:19:01 UTC 2012
Log message for revision 125719:
Prep for coverage.
Moved the long 'includeOverrides' example to narrative docs.
Changed:
U zope.configuration/branches/tseaver-test_cleanup/docs/narr.rst
U zope.configuration/branches/tseaver-test_cleanup/src/zope/configuration/tests/test_xmlconfig.py
-=-
Modified: zope.configuration/branches/tseaver-test_cleanup/docs/narr.rst
===================================================================
--- zope.configuration/branches/tseaver-test_cleanup/docs/narr.rst 2012-05-08 01:18:51 UTC (rev 125718)
+++ zope.configuration/branches/tseaver-test_cleanup/docs/narr.rst 2012-05-08 01:18:57 UTC (rev 125719)
@@ -338,6 +338,232 @@
'order': 0}]
+Overriding Included Configuration
+==================================
+
+When we have conflicting directives, we can resolve them if one of
+the conflicting directives was from a file that included all of
+the others. The problem with this is that this requires that all
+of the overriding directives be in one file, typically the
+top-most including file. This isn't very convenient. Fortunately,
+we can overcome this with the includeOverrides directive. Let's
+look at an example to see how this works.
+
+Look at the file ``bar.zcml`` (in ``zope/configuration/tests/samplepackage``):
+
+- It includes ``bar1.zcml`` and ``bar2.zcml``.
+
+- ``bar1.zcml`` includes ``configure.zcml`` and has a ``foo``
+ directive.
+
+- ``bar2.zcml`` includes ``bar21.zcml``, and has a ``foo``
+ directive that conflicts with one in ``bar1.zcml``.
+
+- ``bar2.zcml`` also overrides a foo directive in ``bar21.zcml``.
+
+- ``bar21.zcml`` has a ``foo`` directive that conflicts with one in in
+ ``configure.zcml``. Whew!
+
+Let's see what happens when we try to process ``bar.zcml``.
+
+.. doctest::
+
+ >>> import os
+ >>> from zope.configuration.config import ConfigurationMachine
+ >>> from zope.configuration.xmlconfig import include
+ >>> from zope.configuration.xmlconfig import registerCommonDirectives
+ >>> context = ConfigurationMachine()
+ >>> registerCommonDirectives(context)
+
+ >>> from zope.configuration.tests import __file__
+ >>> here = os.path.dirname(__file__)
+ >>> path = os.path.join(here, "samplepackage", "bar.zcml")
+ >>> include(context, path)
+
+So far so good, let's look at the configuration actions:
+
+.. doctest::
+
+ >>> from zope.configuration.tests.test_xmlconfig import clean_actions
+ >>> pprint = PrettyPrinter(width=70).pprint
+ >>> pprint(clean_actions(context.actions))
+ [{'discriminator': (('x', 'blah'), ('y', 0)),
+ 'includepath': ['tests/samplepackage/bar.zcml',
+ 'tests/samplepackage/bar1.zcml',
+ 'tests/samplepackage/configure.zcml'],
+ 'info': 'File "tests/samplepackage/configure.zcml", line 12.2-12.29'},
+ {'discriminator': (('x', 'blah'), ('y', 1)),
+ 'includepath': ['tests/samplepackage/bar.zcml',
+ 'tests/samplepackage/bar1.zcml'],
+ 'info': 'File "tests/samplepackage/bar1.zcml", line 5.2-5.24'},
+ {'discriminator': (('x', 'blah'), ('y', 0)),
+ 'includepath': ['tests/samplepackage/bar.zcml',
+ 'tests/samplepackage/bar2.zcml',
+ 'tests/samplepackage/bar21.zcml'],
+ 'info': 'File "tests/samplepackage/bar21.zcml", line 3.2-3.24'},
+ {'discriminator': (('x', 'blah'), ('y', 2)),
+ 'includepath': ['tests/samplepackage/bar.zcml',
+ 'tests/samplepackage/bar2.zcml',
+ 'tests/samplepackage/bar21.zcml'],
+ 'info': 'File "tests/samplepackage/bar21.zcml", line 4.2-4.24'},
+ {'discriminator': (('x', 'blah'), ('y', 2)),
+ 'includepath': ['tests/samplepackage/bar.zcml',
+ 'tests/samplepackage/bar2.zcml'],
+ 'info': 'File "tests/samplepackage/bar2.zcml", line 5.2-5.24'},
+ {'discriminator': (('x', 'blah'), ('y', 1)),
+ 'includepath': ['tests/samplepackage/bar.zcml',
+ 'tests/samplepackage/bar2.zcml'],
+ 'info': 'File "tests/samplepackage/bar2.zcml", line 6.2-6.24'}]
+
+As you can see, there are a number of conflicts (actions with the same
+discriminator). Some of these can be resolved, but many can't, as
+we'll find if we try to execuse the actions:
+
+.. doctest::
+
+ >>> from zope.configuration.config import ConfigurationConflictError
+ >>> from zope.configuration.tests.test_xmlconfig import clean_text_w_paths
+ >>> try:
+ ... v = context.execute_actions()
+ ... except ConfigurationConflictError, v:
+ ... pass
+ >>> print clean_text_w_paths(str(v))
+ Conflicting configuration actions
+ For: (('x', 'blah'), ('y', 0))
+ File "tests/samplepackage/configure.zcml", line 12.2-12.29
+ <test:foo x="blah" y="0" />
+ File "tests/samplepackage/bar21.zcml", line 3.2-3.24
+ <foo x="blah" y="0" />
+ For: (('x', 'blah'), ('y', 1))
+ File "tests/samplepackage/bar1.zcml", line 5.2-5.24
+ <foo x="blah" y="1" />
+ File "tests/samplepackage/bar2.zcml", line 6.2-6.24
+ <foo x="blah" y="1" />
+
+Note that the conflicts for (('x', 'blah'), ('y', 2)) aren't
+included in the error because they could be resolved.
+
+Let's try this again using includeOverrides. We'll include
+baro.zcml which includes bar2.zcml as overrides.
+
+.. doctest::
+
+ >>> context = ConfigurationMachine()
+ >>> registerCommonDirectives(context)
+ >>> path = os.path.join(here, "samplepackage", "baro.zcml")
+ >>> include(context, path)
+
+Now, if we look at the actions:
+
+.. doctest::
+
+ >>> pprint(clean_actions(context.actions))
+ [{'discriminator': (('x', 'blah'), ('y', 0)),
+ 'includepath': ['tests/samplepackage/baro.zcml',
+ 'tests/samplepackage/bar1.zcml',
+ 'tests/samplepackage/configure.zcml'],
+ 'info': 'File "tests/samplepackage/configure.zcml", line 12.2-12.29'},
+ {'discriminator': (('x', 'blah'), ('y', 1)),
+ 'includepath': ['tests/samplepackage/baro.zcml',
+ 'tests/samplepackage/bar1.zcml'],
+ 'info': 'File "tests/samplepackage/bar1.zcml", line 5.2-5.24'},
+ {'discriminator': (('x', 'blah'), ('y', 0)),
+ 'includepath': ['tests/samplepackage/baro.zcml'],
+ 'info': 'File "tests/samplepackage/bar21.zcml", line 3.2-3.24'},
+ {'discriminator': (('x', 'blah'), ('y', 2)),
+ 'includepath': ['tests/samplepackage/baro.zcml'],
+ 'info': 'File "tests/samplepackage/bar2.zcml", line 5.2-5.24'},
+ {'discriminator': (('x', 'blah'), ('y', 1)),
+ 'includepath': ['tests/samplepackage/baro.zcml'],
+ 'info': 'File "tests/samplepackage/bar2.zcml", line 6.2-6.24'}]
+
+We see that:
+
+- The conflicting actions between bar2.zcml and bar21.zcml have
+ been resolved, and
+
+- The remaining (after conflict resolution) actions from bar2.zcml
+ and bar21.zcml have the includepath that they would have if they
+ were defined in baro.zcml and this override the actions from
+ bar1.zcml and configure.zcml.
+
+We can now execute the actions without problem, since the
+remaining conflicts are resolvable:
+
+.. doctest::
+
+ >>> context.execute_actions()
+
+We should now have three entries in foo.data:
+
+.. doctest::
+
+ >>> from zope.configuration.tests.samplepackage import foo
+ >>> from zope.configuration.tests.test_xmlconfig import clean_info_path
+ >>> len(foo.data)
+ 3
+
+ >>> data = foo.data.pop(0)
+ >>> data.args
+ (('x', 'blah'), ('y', 0))
+ >>> print clean_info_path(`data.info`)
+ File "tests/samplepackage/bar21.zcml", line 3.2-3.24
+
+ >>> data = foo.data.pop(0)
+ >>> data.args
+ (('x', 'blah'), ('y', 2))
+ >>> print clean_info_path(`data.info`)
+ File "tests/samplepackage/bar2.zcml", line 5.2-5.24
+
+ >>> data = foo.data.pop(0)
+ >>> data.args
+ (('x', 'blah'), ('y', 1))
+ >>> print clean_info_path(`data.info`)
+ File "tests/samplepackage/bar2.zcml", line 6.2-6.24
+
+
+We expect the exact same results when using includeOverrides with
+the ``files`` argument instead of the ``file`` argument. The
+baro2.zcml file uses the former:
+
+.. doctest::
+
+ >>> context = ConfigurationMachine()
+ >>> registerCommonDirectives(context)
+ >>> path = os.path.join(here, "samplepackage", "baro2.zcml")
+ >>> include(context, path)
+
+Actions look like above:
+
+.. doctest::
+
+ >>> pprint(clean_actions(context.actions))
+ [{'discriminator': (('x', 'blah'), ('y', 0)),
+ 'includepath': ['tests/samplepackage/baro2.zcml',
+ 'tests/samplepackage/bar1.zcml',
+ 'tests/samplepackage/configure.zcml'],
+ 'info': 'File "tests/samplepackage/configure.zcml", line 12.2-12.29'},
+ {'discriminator': (('x', 'blah'), ('y', 1)),
+ 'includepath': ['tests/samplepackage/baro2.zcml',
+ 'tests/samplepackage/bar1.zcml'],
+ 'info': 'File "tests/samplepackage/bar1.zcml", line 5.2-5.24'},
+ {'discriminator': (('x', 'blah'), ('y', 0)),
+ 'includepath': ['tests/samplepackage/baro2.zcml'],
+ 'info': 'File "tests/samplepackage/bar21.zcml", line 3.2-3.24'},
+ {'discriminator': (('x', 'blah'), ('y', 2)),
+ 'includepath': ['tests/samplepackage/baro2.zcml'],
+ 'info': 'File "tests/samplepackage/bar2.zcml", line 5.2-5.24'},
+ {'discriminator': (('x', 'blah'), ('y', 1)),
+ 'includepath': ['tests/samplepackage/baro2.zcml'],
+ 'info': 'File "tests/samplepackage/bar2.zcml", line 6.2-6.24'}]
+
+ >>> context.execute_actions()
+ >>> len(foo.data)
+ 3
+ >>> del foo.data[:]
+
+
+
Making specific directives conditional
======================================
@@ -455,8 +681,8 @@
.. doctest::
- >>> from zope.configuration import xmlconfig
- >>> _ = xmlconfig.string('<include package="zope.configuration.tests.excludedemo" />')
+ >>> from zope.configuration.xmlconfig import string
+ >>> _ = string('<include package="zope.configuration.tests.excludedemo" />')
>>> len(handler.buffer)
3
>>> logged = [x.msg for x in handler.buffer]
@@ -479,7 +705,7 @@
.. doctest::
- >>> _ = xmlconfig.string('<include package="zope.configuration.tests.excludedemo" />')
+ >>> _ = string('<include package="zope.configuration.tests.excludedemo" />')
>>> len(handler.buffer)
3
>>> logged = [x.msg for x in handler.buffer]
@@ -502,7 +728,7 @@
.. doctest::
- >>> _ = xmlconfig.string(
+ >>> _ = string(
... '''
... <configure xmlns="http://namespaces.zope.org/zope">
... <exclude package="zope.configuration.tests.excludedemo.sub" />
Modified: zope.configuration/branches/tseaver-test_cleanup/src/zope/configuration/tests/test_xmlconfig.py
===================================================================
--- zope.configuration/branches/tseaver-test_cleanup/src/zope/configuration/tests/test_xmlconfig.py 2012-05-08 01:18:51 UTC (rev 125718)
+++ zope.configuration/branches/tseaver-test_cleanup/src/zope/configuration/tests/test_xmlconfig.py 2012-05-08 01:18:57 UTC (rev 125719)
@@ -11,314 +11,417 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Test XML configuration (ZCML) machinery.
+"""Test zope.configuration.xmlconfig.
"""
import unittest
-import os
-import re
-from doctest import DocTestSuite, DocFileSuite
-from zope.testing import renormalizing
-from zope.configuration import xmlconfig, config
-from zope.configuration.tests.samplepackage import foo
-from pprint import PrettyPrinter, pprint
+NS = u'ns'
+FOO = u'foo'
+XXX = u'xxx'
+SPLAT = u'splat'
+SPLATV = u'splatv'
+A = u'a'
+AVALUE = u'avalue'
+B = u'b'
+BVALUE = u'bvalue'
-class FauxLocator(object):
- def __init__(self, file, line, column):
- self.file, self.line, self.column = file, line, column
- def getSystemId(self):
- return self.file
- def getLineNumber(self):
- return self.line
- def getColumnNumber(self):
- return self.column
-class FauxContext(object):
+class ZopeXMLConfigurationErrorTests(unittest.TestCase):
- def setInfo(self, info):
- self.info = info
- def getInfo(self):
- return self.info
- def begin(self, name, data, info):
- self.begin_args = name, data
- self.info = info
- def end(self):
- self.end_called = 1
+ def _getTargetClass(self):
+ from zope.configuration.xmlconfig import ZopeXMLConfigurationError
+ return ZopeXMLConfigurationError
-def path(*p):
- return os.path.join(os.path.dirname(__file__), *p)
+ def _makeOne(self, *args, **kw):
+ return self._getTargetClass()(*args, **kw)
-def test_ConfigurationHandler_normal():
- """
- >>> context = FauxContext()
- >>> locator = FauxLocator('tests//sample.zcml', 1, 1)
- >>> handler = xmlconfig.ConfigurationHandler(context)
- >>> handler.setDocumentLocator(locator)
- >>> handler.startElementNS((u"ns", u"foo"), u"foo",
- ... {(u"xxx", u"splat"): u"splatv",
- ... (None, u"a"): u"avalue",
- ... (None, u"b"): u"bvalue",
- ... })
- >>> context.info
- File "tests//sample.zcml", line 1.1
- >>> from pprint import PrettyPrinter
- >>> pprint=PrettyPrinter(width=50).pprint
- >>> pprint(context.begin_args)
- ((u'ns', u'foo'),
- {'a': u'avalue', 'b': u'bvalue'})
- >>> getattr(context, "end_called", 0)
- 0
+class ZopeSAXParseExceptionTests(unittest.TestCase):
- >>> locator.line, locator.column = 7, 16
- >>> handler.endElementNS((u"ns", u"foo"), u"foo")
- >>> context.info
- File "tests//sample.zcml", line 1.1-7.16
- >>> context.end_called
- 1
+ def _getTargetClass(self):
+ from zope.configuration.xmlconfig import ZopeSAXParseException
+ return ZopeSAXParseException
- """
+ def _makeOne(self, *args, **kw):
+ return self._getTargetClass()(*args, **kw)
-def test_ConfigurationHandler_err_start():
- """
- >>> class FauxContext(FauxContext):
- ... def begin(self, *args):
- ... raise AttributeError("xxx")
+class ParserInfoTests(unittest.TestCase):
- >>> context = FauxContext()
- >>> locator = FauxLocator('tests//sample.zcml', 1, 1)
- >>> handler = xmlconfig.ConfigurationHandler(context)
- >>> handler.setDocumentLocator(locator)
+ def _getTargetClass(self):
+ from zope.configuration.xmlconfig import ParserInfo
+ return ParserInfo
- >>> try:
- ... v = handler.startElementNS((u"ns", u"foo"), u"foo",
- ... {(u"xxx", u"splat"): u"splatv",
- ... (None, u"a"): u"avalue",
- ... (None, u"b"): u"bvalue",
- ... })
- ... except xmlconfig.ZopeXMLConfigurationError, v:
- ... pass
- >>> print v
- File "tests//sample.zcml", line 1.1
- AttributeError: xxx
+ def _makeOne(self, *args, **kw):
+ return self._getTargetClass()(*args, **kw)
- """
-def test_ConfigurationHandler_err_end():
- """
+class ConfigurationHandlerTests(unittest.TestCase):
- >>> class FauxContext(FauxContext):
- ... def end(self):
- ... raise AttributeError("xxx")
+ def _getTargetClass(self):
+ from zope.configuration.xmlconfig import ConfigurationHandler
+ return ConfigurationHandler
- >>> context = FauxContext()
- >>> locator = FauxLocator('tests//sample.zcml', 1, 1)
- >>> handler = xmlconfig.ConfigurationHandler(context)
- >>> handler.setDocumentLocator(locator)
+ def _makeOne(self, *args, **kw):
+ return self._getTargetClass()(*args, **kw)
- >>> handler.startElementNS((u"ns", u"foo"), u"foo",
- ... {(u"xxx", u"splat"): u"splatv",
- ... (None, u"a"): u"avalue",
- ... (None, u"b"): u"bvalue",
- ... })
+ def test_normal(self):
+ context = FauxContext()
+ locator = FauxLocator('tests//sample.zcml', 1, 1)
+ handler = self._makeOne(context)
+ handler.setDocumentLocator(locator)
- >>> locator.line, locator.column = 7, 16
- >>> try:
- ... v = handler.endElementNS((u"ns", u"foo"), u"foo")
- ... except xmlconfig.ZopeXMLConfigurationError, v:
- ... pass
- >>> print v
- File "tests//sample.zcml", line 1.1-7.16
- AttributeError: xxx
+ handler.startElementNS((NS, FOO), FOO,
+ {(XXX, SPLAT): SPLATV,
+ (None, A): AVALUE,
+ (None, B): BVALUE,
+ })
+ self.assertEqual(repr(context.info),
+ 'File "tests//sample.zcml", line 1.1')
+ self.assertEqual(context.begin_args,
+ ((NS, FOO),
+ {'a': AVALUE, 'b': BVALUE}))
+ self.assertEqual(getattr(context, "end_called", 0), 0)
- """
+ locator.line, locator.column = 7, 16
+ handler.endElementNS((NS, FOO), FOO)
+ self.assertEqual(repr(context.info),
+ 'File "tests//sample.zcml", line 1.1-7.16')
+ self.assertEqual(context.end_called, 1)
-def clean_info_path(s):
- part1 = s[:6]
- part2 = s[6:s.find('"', 6)]
- part2 = part2[part2.rfind("tests"):]
- part2 = part2.replace(os.sep, '/')
- part3 = s[s.find('"', 6):].rstrip()
- return part1+part2+part3
+ def test_err_start(self):
+ from zope.configuration.xmlconfig import ZopeXMLConfigurationError
+ class ErrorContext(FauxContext):
+ def begin(self, *args):
+ raise AttributeError("xxx")
+ context = ErrorContext()
+ locator = FauxLocator('tests//sample.zcml', 1, 1)
+ handler = self._makeOne(context)
+ handler.setDocumentLocator(locator)
+ self.assertRaises(ZopeXMLConfigurationError,
+ handler.startElementNS, (NS, FOO), FOO,
+ {(XXX, SPLAT): SPLATV,
+ (None, A): AVALUE,
+ (None, B): BVALUE,
+ })
-def clean_path(s):
- s = s[s.rfind("tests"):]
- s = s.replace(os.sep, '/')
- return s
+ def test_err_end(self):
+ from zope.configuration.xmlconfig import ZopeXMLConfigurationError
+ class ErrorContext(FauxContext):
+ def end(self):
+ raise AttributeError("xxx")
+ context = ErrorContext()
+ locator = FauxLocator('tests//sample.zcml', 1, 1)
+ handler = self._makeOne(context)
+ handler.setDocumentLocator(locator)
+ handler.startElementNS((NS, FOO), FOO,
+ {(XXX, SPLAT): SPLATV,
+ (None, A): AVALUE,
+ (None, B): BVALUE,
+ })
-def test_processxmlfile():
- """
+ locator.line, locator.column = 7, 16
+ self.assertRaises(ZopeXMLConfigurationError,
+ handler.endElementNS, (NS, FOO), FOO)
- >>> file = open(path("samplepackage", "configure.zcml"))
- >>> context = config.ConfigurationMachine()
- >>> xmlconfig.registerCommonDirectives(context)
- >>> xmlconfig.processxmlfile(file, context)
- >>> foo.data
- []
+class Test_processxmlfile(unittest.TestCase):
- >>> context.execute_actions()
+ def _callFUT(self, *args, **kw):
+ from zope.configuration.xmlconfig import processxmlfile
+ return processxmlfile(*args, **kw)
- >>> data = foo.data.pop()
+ def test_it(self):
+ from zope.configuration.config import ConfigurationMachine
+ from zope.configuration.xmlconfig import registerCommonDirectives
+ from zope.configuration.tests.samplepackage import foo
+ file = open(path("samplepackage", "configure.zcml"))
+ context = ConfigurationMachine()
+ registerCommonDirectives(context)
+ self._callFUT(file, context)
+ self.assertEqual(foo.data, [])
+ context.execute_actions()
+ data = foo.data.pop()
+ self.assertEqual(data.args, (('x', 'blah'), ('y', 0)))
+ self.assertEqual(clean_info_path(`data.info`),
+ 'File "tests/samplepackage/configure.zcml", line 12.2-12.29')
+ self.assertEqual(clean_info_path(str(data.info)),
+ 'File "tests/samplepackage/configure.zcml", line 12.2-12.29\n'
+ + ' <test:foo x="blah" y="0" />')
+ self.assertEqual(data.package, None)
+ self.assertEqual(data.basepath, None)
- >>> data.args
- (('x', 'blah'), ('y', 0))
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/configure.zcml", line 12.2-12.29
+class Test_openInOrPlain(unittest.TestCase):
- >>> print clean_info_path(str(data.info))
- File "tests/samplepackage/configure.zcml", line 12.2-12.29
- <test:foo x="blah" y="0" />
+ def _callFUT(self, *args, **kw):
+ from zope.configuration.xmlconfig import openInOrPlain
+ return openInOrPlain(*args, **kw)
- >>> data.package
- >>> data.basepath
- """
-def test_file():
- """
+class Test_include(unittest.TestCase):
- >>> file_name = path("samplepackage", "configure.zcml")
- >>> context = xmlconfig.file(file_name)
+ def _callFUT(self, *args, **kw):
+ from zope.configuration.xmlconfig import include
+ return include(*args, **kw)
- >>> data = foo.data.pop()
+ def test_include_by_package(self):
+ from zope.configuration.config import ConfigurationMachine
+ from zope.configuration.xmlconfig import registerCommonDirectives
+ from zope.configuration.tests.samplepackage import foo
+ import zope.configuration.tests.samplepackage as package
+ context = ConfigurationMachine()
+ registerCommonDirectives(context)
+ self._callFUT(context, 'configure.zcml', package)
+ context.execute_actions()
+ data = foo.data.pop()
+ self.assertEqual(data.args, (('x', 'blah'), ('y', 0)))
+ self.assertEqual(clean_info_path(`data.info`),
+ 'File "tests/samplepackage/configure.zcml", line 12.2-12.29')
+ self.assertEqual(clean_info_path(str(data.info)),
+ 'File "tests/samplepackage/configure.zcml", line 12.2-12.29\n'
+ + ' <test:foo x="blah" y="0" />')
+ self.assertTrue(data.package is package)
+ self.assertEqual(data.basepath[-13:], 'samplepackage')
+ self.assertEqual([clean_path(p) for p in data.includepath],
+ ['tests/samplepackage/configure.zcml'])
- >>> data.args
- (('x', 'blah'), ('y', 0))
+ # Not any more
+ ## Including the same file more than once produces an error:
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/configure.zcml", line 12.2-12.29
+ ## >>> try:
+ ## ... xmlconfig.include(context, 'configure.zcml', package)
+ ## ... except xmlconfig.ConfigurationError, e:
+ ## ... 'OK'
+ ## ...
+ ## 'OK'
- >>> print clean_info_path(str(data.info))
- File "tests/samplepackage/configure.zcml", line 12.2-12.29
- <test:foo x="blah" y="0" />
+ def test_include_by_file(self):
+ import os
+ from zope.configuration.config import ConfigurationMachine
+ from zope.configuration.xmlconfig import registerCommonDirectives
+ from zope.configuration.tests.samplepackage import foo
+ context = ConfigurationMachine()
+ registerCommonDirectives(context)
+ here = os.path.dirname(__file__)
+ path = os.path.join(here, "samplepackage", "foo.zcml")
+ self._callFUT(context, path)
+ context.execute_actions()
+ data = foo.data.pop()
+ self.assertEqual(data.args, (('x', 'foo'), ('y', 2)))
+ self.assertEqual(clean_info_path(`data.info`),
+ 'File "tests/samplepackage/foo.zcml.in", line 12.2-12.28')
+ self.assertEqual(clean_info_path(str(data.info)),
+ 'File "tests/samplepackage/foo.zcml.in", line 12.2-12.28\n'
+ + ' <test:foo x="foo" y="2" />')
+ self.assertEqual(data.package, None)
+ self.assertEqual(data.basepath[-13:], 'samplepackage')
+ self.assertEqual([clean_path(p) for p in data.includepath],
+ ['tests/samplepackage/foo.zcml.in'])
- >>> data.package
- >>> print clean_path(data.basepath)
- tests/samplepackage
- """
+ def test_include_by_file_glob(self):
+ import os
+ from zope.configuration.config import ConfigurationMachine
+ from zope.configuration.xmlconfig import registerCommonDirectives
+ from zope.configuration.tests.samplepackage import foo
+ context = ConfigurationMachine()
+ registerCommonDirectives(context)
+ here = os.path.dirname(__file__)
+ path = os.path.join(here, "samplepackage/baz*.zcml")
+ self._callFUT(context, files=path)
+ context.execute_actions()
-def test_include_by_package():
- """
- >>> context = config.ConfigurationMachine()
- >>> xmlconfig.registerCommonDirectives(context)
- >>> import zope.configuration.tests.samplepackage as package
- >>> xmlconfig.include(context, 'configure.zcml', package)
- >>> context.execute_actions()
+ data = foo.data.pop()
+ self.assertEqual(data.args, (('x', 'foo'), ('y', 3)))
+ self.assertEqual(clean_info_path(`data.info`),
+ 'File "tests/samplepackage/baz3.zcml", line 5.2-5.28')
- >>> data = foo.data.pop()
+ self.assertEqual(clean_info_path(str(data.info)),
+ 'File "tests/samplepackage/baz3.zcml", line 5.2-5.28\n'
+ + ' <test:foo x="foo" y="3" />')
+ self.assertEqual(data.package, None)
+ self.assertEqual(data.basepath[-13:], 'samplepackage')
+ self.assertEqual([clean_path(p) for p in data.includepath],
+ ['tests/samplepackage/baz3.zcml'])
- >>> data.args
- (('x', 'blah'), ('y', 0))
+ data = foo.data.pop()
+ self.assertEqual(data.args, (('x', 'foo'), ('y', 2)))
+ self.assertEqual(clean_info_path(`data.info`),
+ 'File "tests/samplepackage/baz2.zcml", line 5.2-5.28')
+ self.assertEqual(clean_info_path(str(data.info)),
+ 'File "tests/samplepackage/baz2.zcml", line 5.2-5.28\n'
+ + ' <test:foo x="foo" y="2" />')
+ self.assertEqual(data.package, None)
+ self.assertEqual(data.basepath[-13:], 'samplepackage')
+ self.assertEqual([clean_path(p) for p in data.includepath],
+ ['tests/samplepackage/baz2.zcml'])
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/configure.zcml", line 12.2-12.29
- >>> print clean_info_path(str(data.info))
- File "tests/samplepackage/configure.zcml", line 12.2-12.29
- <test:foo x="blah" y="0" />
+class Test_exclude(unittest.TestCase):
- >>> data.package is package
- 1
+ def _callFUT(self, *args, **kw):
+ from zope.configuration.xmlconfig import exclude
+ return exclude(*args, **kw)
- >>> data.basepath[-13:]
- 'samplepackage'
- >>> [clean_path(p) for p in data.includepath]
- ['tests/samplepackage/configure.zcml']
+class Test_includeOverrides(unittest.TestCase):
+ def _callFUT(self, *args, **kw):
+ from zope.configuration.xmlconfig import includeOverrides
+ return includeOverrides(*args, **kw)
- """
-# Not any more
-## Including the same file more than once produces an error:
+class Test_file(unittest.TestCase):
-## >>> try:
-## ... xmlconfig.include(context, 'configure.zcml', package)
-## ... except xmlconfig.ConfigurationError, e:
-## ... 'OK'
-## ...
-## 'OK'
+ def _callFUT(self, *args, **kw):
+ from zope.configuration.xmlconfig import file
+ return file(*args, **kw)
-def test_include_by_file():
- """
- >>> context = config.ConfigurationMachine()
- >>> xmlconfig.registerCommonDirectives(context)
- >>> here = os.path.dirname(__file__)
- >>> path = os.path.join(here, "samplepackage", "foo.zcml")
- >>> xmlconfig.include(context, path)
- >>> context.execute_actions()
+ def test_simple(self):
+ from zope.configuration.tests.samplepackage import foo
+ file_name = path("samplepackage", "configure.zcml")
+ context = self._callFUT(file_name)
+ data = foo.data.pop()
+ self.assertEqual(data.args, (('x', 'blah'), ('y', 0)))
+ self.assertEqual(clean_info_path(`data.info`),
+ 'File "tests/samplepackage/configure.zcml", line 12.2-12.29')
+ self.assertEqual(clean_info_path(str(data.info)),
+ 'File "tests/samplepackage/configure.zcml", line 12.2-12.29\n' +
+ ' <test:foo x="blah" y="0" />')
+ self.assertEqual(data.package, None)
+ self.assertEqual(clean_path(data.basepath),
+ 'tests/samplepackage')
- >>> data = foo.data.pop()
- >>> data.args
- (('x', 'foo'), ('y', 2))
+class Test_string(unittest.TestCase):
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/foo.zcml.in", line 12.2-12.28
+ def _callFUT(self, *args, **kw):
+ from zope.configuration.xmlconfig import string
+ return string(*args, **kw)
- >>> print clean_info_path(str(data.info))
- File "tests/samplepackage/foo.zcml.in", line 12.2-12.28
- <test:foo x="foo" y="2" />
- >>> data.package
+class XMLConfigTests(unittest.TestCase):
- >>> data.basepath[-13:]
- 'samplepackage'
+ def setUp(self):
+ from zope.testing.cleanup import CleanUp
+ CleanUp().cleanUp()
- >>> [clean_path(p) for p in data.includepath]
- ['tests/samplepackage/foo.zcml.in']
- """
+ def tearDown(self):
+ from zope.testing.cleanup import CleanUp
+ CleanUp().cleanUp()
-def test_include_by_file_glob():
- """
- >>> context = config.ConfigurationMachine()
- >>> xmlconfig.registerCommonDirectives(context)
- >>> here = os.path.dirname(__file__)
- >>> path = os.path.join(here, "samplepackage/baz*.zcml")
- >>> xmlconfig.include(context, files=path)
- >>> context.execute_actions()
+ def _getTargetClass(self):
+ from zope.configuration.xmlconfig import XMLConfig
+ return XMLConfig
- >>> data = foo.data.pop()
- >>> data.args
- (('x', 'foo'), ('y', 3))
+ def _makeOne(self, *args, **kw):
+ return self._getTargetClass()(*args, **kw)
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/baz3.zcml", line 5.2-5.28
+ def test_XMLConfig(self):
+ import os
+ from zope.configuration.tests.samplepackage import foo
+ here = os.path.dirname(__file__)
+ path = os.path.join(here, "samplepackage", "baro.zcml")
+ x = self._makeOne(path)
+ x() # call to process the actions
+ self.assertEqual(len(foo.data), 3)
- >>> print clean_info_path(str(data.info))
- File "tests/samplepackage/baz3.zcml", line 5.2-5.28
- <test:foo x="foo" y="3" />
+ data = foo.data.pop(0)
+ self.assertEqual(data.args, (('x', 'blah'), ('y', 0)))
+ self.assertEqual(clean_info_path(`data.info`),
+ 'File "tests/samplepackage/bar21.zcml", line 3.2-3.24')
- >>> data.package
+ data = foo.data.pop(0)
+ self.assertEqual(data.args, (('x', 'blah'), ('y', 2)))
+ self.assertEqual(clean_info_path(`data.info`),
+ 'File "tests/samplepackage/bar2.zcml", line 5.2-5.24')
- >>> data.basepath[-13:]
- 'samplepackage'
+ data = foo.data.pop(0)
+ self.assertEqual(data.args, (('x', 'blah'), ('y', 1)))
+ self.assertEqual(clean_info_path(`data.info`),
+ 'File "tests/samplepackage/bar2.zcml", line 6.2-6.24')
- >>> [clean_path(p) for p in data.includepath]
- ['tests/samplepackage/baz3.zcml']
+ def test_XMLConfig_w_module(self):
+ from zope.configuration.tests.samplepackage import foo
+ from zope.configuration.tests import samplepackage as module
+ x = self._makeOne("baro.zcml", module)
+ x() # call to process the actions
+ self.assertEqual(len(foo.data), 3)
- >>> data = foo.data.pop()
- >>> data.args
- (('x', 'foo'), ('y', 2))
+ data = foo.data.pop(0)
+ self.assertEqual(data.args, (('x', 'blah'), ('y', 0)))
+ self.assertEqual(clean_info_path(`data.info`),
+ 'File "tests/samplepackage/bar21.zcml", line 3.2-3.24')
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/baz2.zcml", line 5.2-5.28
+ data = foo.data.pop(0)
+ self.assertEqual(data.args, (('x', 'blah'), ('y', 2)))
+ self.assertEqual(clean_info_path(`data.info`),
+ 'File "tests/samplepackage/bar2.zcml", line 5.2-5.24')
- >>> print clean_info_path(str(data.info))
- File "tests/samplepackage/baz2.zcml", line 5.2-5.28
- <test:foo x="foo" y="2" />
+ data = foo.data.pop(0)
+ self.assertEqual(data.args, (('x', 'blah'), ('y', 1)))
+ self.assertEqual(clean_info_path(`data.info`),
+ 'File "tests/samplepackage/bar2.zcml", line 6.2-6.24')
- >>> data.package
- >>> data.basepath[-13:]
- 'samplepackage'
+class Test_xmlconfig(unittest.TestCase):
- >>> [clean_path(p) for p in data.includepath]
- ['tests/samplepackage/baz2.zcml']
- """
+ def _callFUT(self, *args, **kw):
+ from zope.configuration.xmlconfig import xmlconfig
+ return xmlconfig(*args, **kw)
+
+class Test_testxmlconfig(unittest.TestCase):
+
+ def _callFUT(self, *args, **kw):
+ from zope.configuration.xmlconfig import testxmlconfig
+ return testxmlconfig(*args, **kw)
+
+
+
+class FauxLocator(object):
+ def __init__(self, file, line, column):
+ self.file, self.line, self.column = file, line, column
+ def getSystemId(self):
+ return self.file
+ def getLineNumber(self):
+ return self.line
+ def getColumnNumber(self):
+ return self.column
+
+
+class FauxContext(object):
+
+ def setInfo(self, info):
+ self.info = info
+ def getInfo(self):
+ return self.info
+ def begin(self, name, data, info):
+ self.begin_args = name, data
+ self.info = info
+ def end(self):
+ self.end_called = 1
+
+
+def path(*p):
+ import os
+ return os.path.join(os.path.dirname(__file__), *p)
+
+def clean_info_path(s):
+ import os
+ part1 = s[:6]
+ part2 = s[6:s.find('"', 6)]
+ part2 = part2[part2.rfind("tests"):]
+ part2 = part2.replace(os.sep, '/')
+ part3 = s[s.find('"', 6):].rstrip()
+ return part1+part2+part3
+
+def clean_path(s):
+ import os
+ s = s[s.rfind("tests"):]
+ s = s.replace(os.sep, '/')
+ return s
+
def clean_actions(actions):
return [
{'discriminator': action['discriminator'],
@@ -340,291 +443,21 @@
r.append(line)
return '\n'.join(r)
-def test_includeOverrides():
- """
- When we have conflicting directives, we can resolve them if one of
- the conflicting directives was from a file that included all of
- the others. The problem with this is that this requires that all
- of the overriding directives be in one file, typically the
- top-most including file. This isn't very convenient. Fortunately,
- we can overcome this with the includeOverrides directive. Let's
- look at an example to see how this works.
- Look at the file bar.zcml. It includes bar1.zcml and bar2.zcml.
- bar2.zcml includes configure.zcml and has a foo
- directive. bar2.zcml includes bar21.zcml. bar2.zcml has a foo
- directive that conflicts with one in bar1.zcml. bar2.zcml also
- overrides a foo directive in bar21.zcml. bar21.zcml has a foo
- directive that conflicts with one in in configure.zcml. Whew!
-
- Let's see what happens when we try to process bar.zcml.
-
- >>> context = config.ConfigurationMachine()
- >>> xmlconfig.registerCommonDirectives(context)
-
- >>> here = os.path.dirname(__file__)
- >>> path = os.path.join(here, "samplepackage", "bar.zcml")
- >>> xmlconfig.include(context, path)
-
- So far so good, let's look at the configuration actions:
-
- >>> pprint=PrettyPrinter(width=70).pprint
- >>> pprint(clean_actions(context.actions))
- [{'discriminator': (('x', 'blah'), ('y', 0)),
- 'includepath': ['tests/samplepackage/bar.zcml',
- 'tests/samplepackage/bar1.zcml',
- 'tests/samplepackage/configure.zcml'],
- 'info': 'File "tests/samplepackage/configure.zcml", line 12.2-12.29'},
- {'discriminator': (('x', 'blah'), ('y', 1)),
- 'includepath': ['tests/samplepackage/bar.zcml',
- 'tests/samplepackage/bar1.zcml'],
- 'info': 'File "tests/samplepackage/bar1.zcml", line 5.2-5.24'},
- {'discriminator': (('x', 'blah'), ('y', 0)),
- 'includepath': ['tests/samplepackage/bar.zcml',
- 'tests/samplepackage/bar2.zcml',
- 'tests/samplepackage/bar21.zcml'],
- 'info': 'File "tests/samplepackage/bar21.zcml", line 3.2-3.24'},
- {'discriminator': (('x', 'blah'), ('y', 2)),
- 'includepath': ['tests/samplepackage/bar.zcml',
- 'tests/samplepackage/bar2.zcml',
- 'tests/samplepackage/bar21.zcml'],
- 'info': 'File "tests/samplepackage/bar21.zcml", line 4.2-4.24'},
- {'discriminator': (('x', 'blah'), ('y', 2)),
- 'includepath': ['tests/samplepackage/bar.zcml',
- 'tests/samplepackage/bar2.zcml'],
- 'info': 'File "tests/samplepackage/bar2.zcml", line 5.2-5.24'},
- {'discriminator': (('x', 'blah'), ('y', 1)),
- 'includepath': ['tests/samplepackage/bar.zcml',
- 'tests/samplepackage/bar2.zcml'],
- 'info': 'File "tests/samplepackage/bar2.zcml", line 6.2-6.24'}]
-
- As you can see, there are a number of conflicts (actions with the same
- discriminator). Some of these can be resolved, but many can't, as
- we'll find if we try to execuse the actions:
-
- >>> try:
- ... v = context.execute_actions()
- ... except config.ConfigurationConflictError, v:
- ... pass
- >>> print clean_text_w_paths(str(v))
- Conflicting configuration actions
- For: (('x', 'blah'), ('y', 0))
- File "tests/samplepackage/configure.zcml", line 12.2-12.29
- <test:foo x="blah" y="0" />
- File "tests/samplepackage/bar21.zcml", line 3.2-3.24
- <foo x="blah" y="0" />
- For: (('x', 'blah'), ('y', 1))
- File "tests/samplepackage/bar1.zcml", line 5.2-5.24
- <foo x="blah" y="1" />
- File "tests/samplepackage/bar2.zcml", line 6.2-6.24
- <foo x="blah" y="1" />
-
- Note that the conflicts for (('x', 'blah'), ('y', 2)) aren't
- included in the error because they could be resolved.
-
- Let's try this again using includeOverrides. We'll include
- baro.zcml which includes bar2.zcml as overrides.
-
- >>> context = config.ConfigurationMachine()
- >>> xmlconfig.registerCommonDirectives(context)
- >>> path = os.path.join(here, "samplepackage", "baro.zcml")
- >>> xmlconfig.include(context, path)
-
- Now, if we look at the actions:
-
- >>> pprint(clean_actions(context.actions))
- [{'discriminator': (('x', 'blah'), ('y', 0)),
- 'includepath': ['tests/samplepackage/baro.zcml',
- 'tests/samplepackage/bar1.zcml',
- 'tests/samplepackage/configure.zcml'],
- 'info': 'File "tests/samplepackage/configure.zcml", line 12.2-12.29'},
- {'discriminator': (('x', 'blah'), ('y', 1)),
- 'includepath': ['tests/samplepackage/baro.zcml',
- 'tests/samplepackage/bar1.zcml'],
- 'info': 'File "tests/samplepackage/bar1.zcml", line 5.2-5.24'},
- {'discriminator': (('x', 'blah'), ('y', 0)),
- 'includepath': ['tests/samplepackage/baro.zcml'],
- 'info': 'File "tests/samplepackage/bar21.zcml", line 3.2-3.24'},
- {'discriminator': (('x', 'blah'), ('y', 2)),
- 'includepath': ['tests/samplepackage/baro.zcml'],
- 'info': 'File "tests/samplepackage/bar2.zcml", line 5.2-5.24'},
- {'discriminator': (('x', 'blah'), ('y', 1)),
- 'includepath': ['tests/samplepackage/baro.zcml'],
- 'info': 'File "tests/samplepackage/bar2.zcml", line 6.2-6.24'}]
-
- We see that:
-
- - The conflicting actions between bar2.zcml and bar21.zcml have
- been resolved, and
-
- - The remaining (after conflict resolution) actions from bar2.zcml
- and bar21.zcml have the includepath that they would have if they
- were defined in baro.zcml and this override the actions from
- bar1.zcml and configure.zcml.
-
- We can now execute the actions without problem, since the
- remaining conflicts are resolvable:
-
- >>> context.execute_actions()
-
- We should now have three entries in foo.data:
-
- >>> len(foo.data)
- 3
-
- >>> data = foo.data.pop(0)
- >>> data.args
- (('x', 'blah'), ('y', 0))
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/bar21.zcml", line 3.2-3.24
-
- >>> data = foo.data.pop(0)
- >>> data.args
- (('x', 'blah'), ('y', 2))
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/bar2.zcml", line 5.2-5.24
-
- >>> data = foo.data.pop(0)
- >>> data.args
- (('x', 'blah'), ('y', 1))
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/bar2.zcml", line 6.2-6.24
-
-
- We expect the exact same results when using includeOverrides with
- the ``files`` argument instead of the ``file`` argument. The
- baro2.zcml file uses the former:
-
- >>> context = config.ConfigurationMachine()
- >>> xmlconfig.registerCommonDirectives(context)
- >>> path = os.path.join(here, "samplepackage", "baro2.zcml")
- >>> xmlconfig.include(context, path)
-
- Actions look like above:
-
- >>> pprint(clean_actions(context.actions))
- [{'discriminator': (('x', 'blah'), ('y', 0)),
- 'includepath': ['tests/samplepackage/baro2.zcml',
- 'tests/samplepackage/bar1.zcml',
- 'tests/samplepackage/configure.zcml'],
- 'info': 'File "tests/samplepackage/configure.zcml", line 12.2-12.29'},
- {'discriminator': (('x', 'blah'), ('y', 1)),
- 'includepath': ['tests/samplepackage/baro2.zcml',
- 'tests/samplepackage/bar1.zcml'],
- 'info': 'File "tests/samplepackage/bar1.zcml", line 5.2-5.24'},
- {'discriminator': (('x', 'blah'), ('y', 0)),
- 'includepath': ['tests/samplepackage/baro2.zcml'],
- 'info': 'File "tests/samplepackage/bar21.zcml", line 3.2-3.24'},
- {'discriminator': (('x', 'blah'), ('y', 2)),
- 'includepath': ['tests/samplepackage/baro2.zcml'],
- 'info': 'File "tests/samplepackage/bar2.zcml", line 5.2-5.24'},
- {'discriminator': (('x', 'blah'), ('y', 1)),
- 'includepath': ['tests/samplepackage/baro2.zcml'],
- 'info': 'File "tests/samplepackage/bar2.zcml", line 6.2-6.24'}]
-
- >>> context.execute_actions()
- >>> len(foo.data)
- 3
- >>> del foo.data[:]
-
- """
-
-def test_XMLConfig():
- """Test processing a configuration file.
-
- We'll use the same example from test_includeOverrides:
-
- >>> here = os.path.dirname(__file__)
- >>> path = os.path.join(here, "samplepackage", "baro.zcml")
-
- First, process the configuration file:
-
- >>> x = xmlconfig.XMLConfig(path)
-
- Second, call the resulting object to process the actions:
-
- >>> x()
-
- And verify the data as above:
-
- >>> len(foo.data)
- 3
-
- >>> data = foo.data.pop(0)
- >>> data.args
- (('x', 'blah'), ('y', 0))
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/bar21.zcml", line 3.2-3.24
-
- >>> data = foo.data.pop(0)
- >>> data.args
- (('x', 'blah'), ('y', 2))
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/bar2.zcml", line 5.2-5.24
-
- >>> data = foo.data.pop(0)
- >>> data.args
- (('x', 'blah'), ('y', 1))
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/bar2.zcml", line 6.2-6.24
-
- Finally, clean up.
-
- >>> from zope.testing.cleanup import CleanUp
- >>> CleanUp().cleanUp()
- """
-
-def test_XMLConfig_w_module():
- """Test processing a configuration file for a module.
-
- We'll use the same example from test_includeOverrides:
-
- >>> import zope.configuration.tests.samplepackage as module
-
- First, process the configuration file:
-
- >>> x = xmlconfig.XMLConfig("baro.zcml", module)
-
- Second, call the resulting object to process the actions:
-
- >>> x()
-
- And verify the data as above:
-
- >>> len(foo.data)
- 3
-
- >>> data = foo.data.pop(0)
- >>> data.args
- (('x', 'blah'), ('y', 0))
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/bar21.zcml", line 3.2-3.24
-
- >>> data = foo.data.pop(0)
- >>> data.args
- (('x', 'blah'), ('y', 2))
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/bar2.zcml", line 5.2-5.24
-
- >>> data = foo.data.pop(0)
- >>> data.args
- (('x', 'blah'), ('y', 1))
- >>> print clean_info_path(`data.info`)
- File "tests/samplepackage/bar2.zcml", line 6.2-6.24
-
- Finally, clean up.
-
- >>> from zope.testing.cleanup import CleanUp
- >>> CleanUp().cleanUp()
- """
-
-
-
def test_suite():
return unittest.TestSuite((
- DocTestSuite('zope.configuration.xmlconfig'),
- DocTestSuite(),
- ))
-
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
+ unittest.makeSuite(ZopeXMLConfigurationErrorTests),
+ unittest.makeSuite(ZopeSAXParseExceptionTests),
+ unittest.makeSuite(ParserInfoTests),
+ unittest.makeSuite(ConfigurationHandlerTests),
+ unittest.makeSuite(Test_processxmlfile),
+ unittest.makeSuite(Test_openInOrPlain),
+ unittest.makeSuite(Test_include),
+ unittest.makeSuite(Test_exclude),
+ unittest.makeSuite(Test_includeOverrides),
+ unittest.makeSuite(Test_file),
+ unittest.makeSuite(Test_string),
+ unittest.makeSuite(XMLConfigTests),
+ unittest.makeSuite(Test_xmlconfig),
+ unittest.makeSuite(Test_testxmlconfig),
+ ))
More information about the checkins
mailing list