[Testbot] Plone 5.0 - Python 2.7 - Build # 2531 - Still failing! - 1 failure(s)
jenkins at plone.org
jenkins at plone.org
Fri May 30 19:04:15 UTC 2014
-------------------------------------------------------------------------------
Plone 5.0 - Python 2.7 - Build # 2531 - Still Failing!
-------------------------------------------------------------------------------
http://jenkins.plone.org/job/plone-5.0-python-2.7/2531/
-------------------------------------------------------------------------------
CHANGES
-------------------------------------------------------------------------------
Repository: plone.supermodel
Branch: refs/heads/master
Date: 2013-11-17T15:00:56-08:00
Author: Steve McMahon (smcmahon) <steve at dcn.org>
Commit: https://github.com/plone/plone.supermodel/commit/7f08549047533668f928e2b87613b6e9b4d4ed28
First draft; no serialization.
Files changed:
M plone/supermodel/interfaces.py
M plone/supermodel/parser.py
M plone/supermodel/schema.txt
M plone/supermodel/tests.py
diff --git a/plone/supermodel/interfaces.py b/plone/supermodel/interfaces.py
index bd59199..f9fd541 100644
--- a/plone/supermodel/interfaces.py
+++ b/plone/supermodel/interfaces.py
@@ -221,3 +221,12 @@ class IDefaultFactory(Interface):
def __call__():
"""Returns a default value for the field."""
+
+
+class IInvariant(Interface):
+ """Marker interface for a callable used as a form invariant.
+ """
+
+ def __call__(data):
+ """Returns None or raises zope.interface.Invalid
+ """
diff --git a/plone/supermodel/parser.py b/plone/supermodel/parser.py
index 5b01f71..c3f6e7e 100644
--- a/plone/supermodel/parser.py
+++ b/plone/supermodel/parser.py
@@ -10,6 +10,7 @@
from zope.dottedname.resolve import resolve
+from plone.supermodel.interfaces import IInvariant
from plone.supermodel.interfaces import ISchemaPolicy
from plone.supermodel.interfaces import IFieldExportImportHandler
@@ -144,7 +145,8 @@ def readField(fieldElement, schemaAttributes, fieldElements, baseFields):
readField(fieldElement, schemaAttributes, fieldElements, baseFields)
parseinfo.stack.pop()
- # Read fieldsets and their fields
+ # Read invariants, fieldsets and their fields
+ invariants = []
fieldsets = []
fieldsets_by_name = {}
@@ -175,17 +177,29 @@ def readField(fieldElement, schemaAttributes, fieldElements, baseFields):
if parsed_fieldName:
fieldset.fields.append(parsed_fieldName)
parseinfo.stack.pop()
+ elif subelement.tag == ns('invariant'):
+ dotted = subelement.text
+ invariant = resolve(dotted)
+ if not IInvariant.providedBy(invariant):
+ raise ImportError(
+ u"Invariant functions must provide plone.supermodel.interfaces.IInvariant"
+ )
+ invariants.append(invariant)
parseinfo.stack.pop()
schema = SchemaClass(name=policy_util.name(schemaName, tree),
bases=bases + policy_util.bases(schemaName, tree) + (Schema,),
__module__=policy_util.module(schemaName, tree),
attrs=schemaAttributes)
-
- schema.setTaggedValue(FIELDSETS_KEY, fieldsets)
+
+ # add invariants to schema as tagged values
+ if invariants:
+ schema_invariants = schema.queryTaggedValue('invariants', [])
+ schema.setTaggedValue('invariants', schema_invariants + invariants)
# Save fieldsets
-
+ schema.setTaggedValue(FIELDSETS_KEY, fieldsets)
+
# Let metadata handlers write metadata
for handler_name, metadata_handler in field_metadata_handlers:
for fieldName in schema:
diff --git a/plone/supermodel/schema.txt b/plone/supermodel/schema.txt
index be8a72a..1362732 100644
--- a/plone/supermodel/schema.txt
+++ b/plone/supermodel/schema.txt
@@ -445,6 +445,52 @@ fieldset.
</schema>
</model>
+Invariant Support
+-----------------
+
+ >>> schema = """\
+ ... <?xml version="1.0" encoding="UTF-8"?>
+ ... <model xmlns="http://namespaces.plone.org/supermodel/schema">
+ ... <schema>
+ ... <invariant>plone.supermodel.tests.dummy_invariant</invariant>
+ ... <field type="zope.schema.Text" name="description">
+ ... <title>Description</title>
+ ... <description>A short summary</description>
+ ... </field>
+ ... <field type="zope.schema.Int" name="age">
+ ... <title>Age</title>
+ ... </field>
+ ... </schema>
+ ... </model>
+ ... """
+
+ >>> model = loadString(schema)
+ >>> model.schema.getTaggedValue('invariants')
+ [<function dummy_invariant at ...>]
+
+ >>> schema = """\
+ ... <?xml version="1.0" encoding="UTF-8"?>
+ ... <model xmlns="http://namespaces.plone.org/supermodel/schema">
+ ... <schema>
+ ... <invariant>plone.supermodel.tests.dummy_unmarkedInvariant</invariant>
+ ... <field type="zope.schema.Text" name="description">
+ ... <title>Description</title>
+ ... <description>A short summary</description>
+ ... </field>
+ ... <field type="zope.schema.Int" name="age">
+ ... <title>Age</title>
+ ... </field>
+ ... </schema>
+ ... </model>
+ ... """
+
+ >>> model = loadString(schema)
+ Traceback (most recent call last):
+ ...
+ SupermodelParseError: Invariant functions must provide plone.supermodel.interfaces.IInvariant
+ File "<unknown>", line ...
+
+
Internationalization
--------------------
diff --git a/plone/supermodel/tests.py b/plone/supermodel/tests.py
index 8ab9e58..39e82e6 100644
--- a/plone/supermodel/tests.py
+++ b/plone/supermodel/tests.py
@@ -15,6 +15,7 @@
from plone.supermodel import utils
from plone.supermodel.interfaces import IDefaultFactory
+from plone.supermodel.interfaces import IInvariant
class IBase(Interface):
@@ -67,6 +68,16 @@ def dummy_defaultBadFactory():
return u'b'
+ at provider(IInvariant)
+def dummy_invariant(data):
+ return None
+
+
+def dummy_unmarkedInvariant(data):
+ """ lacks IInvariant marker """
+ return None
+
+
class TestUtils(unittest.TestCase):
def test_syncSchema(self):
Repository: plone.supermodel
Branch: refs/heads/master
Date: 2013-11-17T15:35:16-08:00
Author: Steve McMahon (smcmahon) <steve at dcn.org>
Commit: https://github.com/plone/plone.supermodel/commit/0b3f3ad7257752318e04d2a9c6daf2affbb894da
Provide serializaation of invariants.
Files changed:
M plone/supermodel/schema.txt
M plone/supermodel/serializer.py
diff --git a/plone/supermodel/schema.txt b/plone/supermodel/schema.txt
index 1362732..fe93b50 100644
--- a/plone/supermodel/schema.txt
+++ b/plone/supermodel/schema.txt
@@ -448,6 +448,9 @@ fieldset.
Invariant Support
-----------------
+We may specify an invariant for the form via the "invariant" tag with
+a dotted name for the invariant function.
+
>>> schema = """\
... <?xml version="1.0" encoding="UTF-8"?>
... <model xmlns="http://namespaces.plone.org/supermodel/schema">
@@ -468,6 +471,25 @@ Invariant Support
>>> model.schema.getTaggedValue('invariants')
[<function dummy_invariant at ...>]
+The model's serialization should include the invariant.
+
+ >>> print serializeModel(model) # doctest: +NORMALIZE_WHITESPACE
+ <model xmlns="http://namespaces.plone.org/supermodel/schema">
+ <schema>
+ <invariant>plone.supermodel.tests.dummy_invariant</invariant>
+ <field name="description" type="zope.schema.Text">
+ <description>A short summary</description>
+ <title>Description</title>
+ </field>
+ <field name="age" type="zope.schema.Int">
+ <title>Age</title>
+ </field>
+ </schema>
+ </model>
+
+Invariant functions must provide plone.supermodel.interfaces.IInvariant
+or we won't accept them.
+
>>> schema = """\
... <?xml version="1.0" encoding="UTF-8"?>
... <model xmlns="http://namespaces.plone.org/supermodel/schema">
diff --git a/plone/supermodel/serializer.py b/plone/supermodel/serializer.py
index 1964903..b6d98e1 100644
--- a/plone/supermodel/serializer.py
+++ b/plone/supermodel/serializer.py
@@ -93,6 +93,11 @@ def writeField(field, parentElement):
bases = [b.__identifier__ for b in schema.__bases__ if b is not Schema]
if bases:
schema_element.set('based-on', ' '.join(bases))
+
+ for invariant in schema.queryTaggedValue('invariants', []):
+ invariant_element = etree.Element('invariant')
+ invariant_element.text = "%s.%s" % (invariant.__module__, invariant.__name__
+ schema_element.append(invariant_element)
for fieldName in non_fieldset_fields:
field = schema[fieldName]
Repository: plone.supermodel
Branch: refs/heads/master
Date: 2013-11-17T15:45:49-08:00
Author: Steve McMahon (smcmahon) <steve at dcn.org>
Commit: https://github.com/plone/plone.supermodel/commit/42193388e40ad1d6933dcbdef299eba14dd83930
Check multiple invariants; test validateInvariants.
Files changed:
M plone/supermodel/schema.txt
M plone/supermodel/serializer.py
M plone/supermodel/tests.py
diff --git a/plone/supermodel/schema.txt b/plone/supermodel/schema.txt
index fe93b50..d34a2dc 100644
--- a/plone/supermodel/schema.txt
+++ b/plone/supermodel/schema.txt
@@ -448,7 +448,7 @@ fieldset.
Invariant Support
-----------------
-We may specify an invariant for the form via the "invariant" tag with
+We may specify one or more invariants for the form via the "invariant" tag with
a dotted name for the invariant function.
>>> schema = """\
@@ -456,6 +456,7 @@ a dotted name for the invariant function.
... <model xmlns="http://namespaces.plone.org/supermodel/schema">
... <schema>
... <invariant>plone.supermodel.tests.dummy_invariant</invariant>
+ ... <invariant>plone.supermodel.tests.dummy_invariant_prime</invariant>
... <field type="zope.schema.Text" name="description">
... <title>Description</title>
... <description>A short summary</description>
@@ -469,7 +470,15 @@ a dotted name for the invariant function.
>>> model = loadString(schema)
>>> model.schema.getTaggedValue('invariants')
- [<function dummy_invariant at ...>]
+ [<function dummy_invariant at ...>, <function dummy_invariant_prime at ...>]
+
+When invariants are checked for our model.schema, we'll see our invariant
+in action.
+
+ >>> model.schema.validateInvariants(object())
+ Traceback (most recent call last):
+ ...
+ Invalid: Yikes! Invalid
The model's serialization should include the invariant.
@@ -477,6 +486,7 @@ The model's serialization should include the invariant.
<model xmlns="http://namespaces.plone.org/supermodel/schema">
<schema>
<invariant>plone.supermodel.tests.dummy_invariant</invariant>
+ <invariant>plone.supermodel.tests.dummy_invariant_prime</invariant>
<field name="description" type="zope.schema.Text">
<description>A short summary</description>
<title>Description</title>
diff --git a/plone/supermodel/serializer.py b/plone/supermodel/serializer.py
index b6d98e1..2e56561 100644
--- a/plone/supermodel/serializer.py
+++ b/plone/supermodel/serializer.py
@@ -96,7 +96,7 @@ def writeField(field, parentElement):
for invariant in schema.queryTaggedValue('invariants', []):
invariant_element = etree.Element('invariant')
- invariant_element.text = "%s.%s" % (invariant.__module__, invariant.__name__
+ invariant_element.text = "%s.%s" % (invariant.__module__, invariant.__name__)
schema_element.append(invariant_element)
for fieldName in non_fieldset_fields:
diff --git a/plone/supermodel/tests.py b/plone/supermodel/tests.py
index 39e82e6..aeb41a9 100644
--- a/plone/supermodel/tests.py
+++ b/plone/supermodel/tests.py
@@ -5,6 +5,7 @@
from lxml import etree
from zope.interface import Interface, implements, alsoProvides, provider
+from zope.interface import Invalid
import zope.component.testing
from zope.schema import getFieldNamesInOrder
@@ -70,6 +71,11 @@ def dummy_defaultBadFactory():
@provider(IInvariant)
def dummy_invariant(data):
+ raise Invalid(u"Yikes! Invalid")
+
+
+ at provider(IInvariant)
+def dummy_invariant_prime(data):
return None
Repository: plone.supermodel
Branch: refs/heads/master
Date: 2013-11-17T17:06:07-08:00
Author: Steve McMahon (smcmahon) <steve at dcn.org>
Commit: https://github.com/plone/plone.supermodel/commit/b802097d10d35d766833bb25cf6b4097dc7671f0
Update change log for invariants
Files changed:
M CHANGES.rst
diff --git a/CHANGES.rst b/CHANGES.rst
index ab425eb..09349b3 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,6 +4,10 @@ Changelog
1.2.4 (unreleased)
------------------
+- Add invariant tag, a sub-element of schema, that accepts a dotted name as
+ a value. Invariants must provide plone.supermodel.interface.IInvariant.
+ [smcmahon]
+
- Replace deprecated test assert statements.
[timo]
@@ -14,6 +18,7 @@ Changelog
- Add defaultFactory tag for Dexterity XML. Define an interface
IDefaultFactory. defaultFactories specified via XML must implement it or
IContextAwareDefaultFactory.
+ [smcmahon]
1.2.2 (2013-05-23)
Repository: plone.supermodel
Branch: refs/heads/master
Date: 2014-05-30T12:10:48-06:00
Author: Sean Upton (seanupton) <sdupton at gmail.com>
Commit: https://github.com/plone/plone.supermodel/commit/76b451179b14874c5daa3b886f7a5a5e2cc59afb
Merge pull request #5 from plone/invariant
Add invariant support
Files changed:
M CHANGES.rst
M plone/supermodel/interfaces.py
M plone/supermodel/parser.py
M plone/supermodel/schema.txt
M plone/supermodel/serializer.py
M plone/supermodel/tests.py
diff --git a/CHANGES.rst b/CHANGES.rst
index 4f07a1d..d90c4c6 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -10,6 +10,10 @@ Changelog
1.2.4 (2014-01-27)
------------------
+- Add invariant tag, a sub-element of schema, that accepts a dotted name as
+ a value. Invariants must provide plone.supermodel.interface.IInvariant.
+ [smcmahon]
+
- Replace deprecated test assert statements.
[timo]
@@ -20,6 +24,7 @@ Changelog
- Add defaultFactory tag for Dexterity XML. Define an interface
IDefaultFactory. defaultFactories specified via XML must implement it or
IContextAwareDefaultFactory.
+ [smcmahon]
1.2.2 (2013-05-23)
diff --git a/plone/supermodel/interfaces.py b/plone/supermodel/interfaces.py
index bd59199..f9fd541 100644
--- a/plone/supermodel/interfaces.py
+++ b/plone/supermodel/interfaces.py
@@ -221,3 +221,12 @@ class IDefaultFactory(Interface):
def __call__():
"""Returns a default value for the field."""
+
+
+class IInvariant(Interface):
+ """Marker interface for a callable used as a form invariant.
+ """
+
+ def __call__(data):
+ """Returns None or raises zope.interface.Invalid
+ """
diff --git a/plone/supermodel/parser.py b/plone/supermodel/parser.py
index 5b01f71..c3f6e7e 100644
--- a/plone/supermodel/parser.py
+++ b/plone/supermodel/parser.py
@@ -10,6 +10,7 @@
from zope.dottedname.resolve import resolve
+from plone.supermodel.interfaces import IInvariant
from plone.supermodel.interfaces import ISchemaPolicy
from plone.supermodel.interfaces import IFieldExportImportHandler
@@ -144,7 +145,8 @@ def readField(fieldElement, schemaAttributes, fieldElements, baseFields):
readField(fieldElement, schemaAttributes, fieldElements, baseFields)
parseinfo.stack.pop()
- # Read fieldsets and their fields
+ # Read invariants, fieldsets and their fields
+ invariants = []
fieldsets = []
fieldsets_by_name = {}
@@ -175,17 +177,29 @@ def readField(fieldElement, schemaAttributes, fieldElements, baseFields):
if parsed_fieldName:
fieldset.fields.append(parsed_fieldName)
parseinfo.stack.pop()
+ elif subelement.tag == ns('invariant'):
+ dotted = subelement.text
+ invariant = resolve(dotted)
+ if not IInvariant.providedBy(invariant):
+ raise ImportError(
+ u"Invariant functions must provide plone.supermodel.interfaces.IInvariant"
+ )
+ invariants.append(invariant)
parseinfo.stack.pop()
schema = SchemaClass(name=policy_util.name(schemaName, tree),
bases=bases + policy_util.bases(schemaName, tree) + (Schema,),
__module__=policy_util.module(schemaName, tree),
attrs=schemaAttributes)
-
- schema.setTaggedValue(FIELDSETS_KEY, fieldsets)
+
+ # add invariants to schema as tagged values
+ if invariants:
+ schema_invariants = schema.queryTaggedValue('invariants', [])
+ schema.setTaggedValue('invariants', schema_invariants + invariants)
# Save fieldsets
-
+ schema.setTaggedValue(FIELDSETS_KEY, fieldsets)
+
# Let metadata handlers write metadata
for handler_name, metadata_handler in field_metadata_handlers:
for fieldName in schema:
diff --git a/plone/supermodel/schema.txt b/plone/supermodel/schema.txt
index be8a72a..d34a2dc 100644
--- a/plone/supermodel/schema.txt
+++ b/plone/supermodel/schema.txt
@@ -445,6 +445,84 @@ fieldset.
</schema>
</model>
+Invariant Support
+-----------------
+
+We may specify one or more invariants for the form via the "invariant" tag with
+a dotted name for the invariant function.
+
+ >>> schema = """\
+ ... <?xml version="1.0" encoding="UTF-8"?>
+ ... <model xmlns="http://namespaces.plone.org/supermodel/schema">
+ ... <schema>
+ ... <invariant>plone.supermodel.tests.dummy_invariant</invariant>
+ ... <invariant>plone.supermodel.tests.dummy_invariant_prime</invariant>
+ ... <field type="zope.schema.Text" name="description">
+ ... <title>Description</title>
+ ... <description>A short summary</description>
+ ... </field>
+ ... <field type="zope.schema.Int" name="age">
+ ... <title>Age</title>
+ ... </field>
+ ... </schema>
+ ... </model>
+ ... """
+
+ >>> model = loadString(schema)
+ >>> model.schema.getTaggedValue('invariants')
+ [<function dummy_invariant at ...>, <function dummy_invariant_prime at ...>]
+
+When invariants are checked for our model.schema, we'll see our invariant
+in action.
+
+ >>> model.schema.validateInvariants(object())
+ Traceback (most recent call last):
+ ...
+ Invalid: Yikes! Invalid
+
+The model's serialization should include the invariant.
+
+ >>> print serializeModel(model) # doctest: +NORMALIZE_WHITESPACE
+ <model xmlns="http://namespaces.plone.org/supermodel/schema">
+ <schema>
+ <invariant>plone.supermodel.tests.dummy_invariant</invariant>
+ <invariant>plone.supermodel.tests.dummy_invariant_prime</invariant>
+ <field name="description" type="zope.schema.Text">
+ <description>A short summary</description>
+ <title>Description</title>
+ </field>
+ <field name="age" type="zope.schema.Int">
+ <title>Age</title>
+ </field>
+ </schema>
+ </model>
+
+Invariant functions must provide plone.supermodel.interfaces.IInvariant
+or we won't accept them.
+
+ >>> schema = """\
+ ... <?xml version="1.0" encoding="UTF-8"?>
+ ... <model xmlns="http://namespaces.plone.org/supermodel/schema">
+ ... <schema>
+ ... <invariant>plone.supermodel.tests.dummy_unmarkedInvariant</invariant>
+ ... <field type="zope.schema.Text" name="description">
+ ... <title>Description</title>
+ ... <description>A short summary</description>
+ ... </field>
+ ... <field type="zope.schema.Int" name="age">
+ ... <title>Age</title>
+ ... </field>
+ ... </schema>
+ ... </model>
+ ... """
+
+ >>> model = loadString(schema)
+ Traceback (most recent call last):
+ ...
+ SupermodelParseError: Invariant functions must provide plone.supermodel.interfaces.IInvariant
+ File "<unknown>", line ...
+
+
Internationalization
--------------------
diff --git a/plone/supermodel/serializer.py b/plone/supermodel/serializer.py
index 1964903..2e56561 100644
--- a/plone/supermodel/serializer.py
+++ b/plone/supermodel/serializer.py
@@ -93,6 +93,11 @@ def writeField(field, parentElement):
bases = [b.__identifier__ for b in schema.__bases__ if b is not Schema]
if bases:
schema_element.set('based-on', ' '.join(bases))
+
+ for invariant in schema.queryTaggedValue('invariants', []):
+ invariant_element = etree.Element('invariant')
+ invariant_element.text = "%s.%s" % (invariant.__module__, invariant.__name__)
+ schema_element.append(invariant_element)
for fieldName in non_fieldset_fields:
field = schema[fieldName]
diff --git a/plone/supermodel/tests.py b/plone/supermodel/tests.py
index 8ab9e58..aeb41a9 100644
--- a/plone/supermodel/tests.py
+++ b/plone/supermodel/tests.py
@@ -5,6 +5,7 @@
from lxml import etree
from zope.interface import Interface, implements, alsoProvides, provider
+from zope.interface import Invalid
import zope.component.testing
from zope.schema import getFieldNamesInOrder
@@ -15,6 +16,7 @@
from plone.supermodel import utils
from plone.supermodel.interfaces import IDefaultFactory
+from plone.supermodel.interfaces import IInvariant
class IBase(Interface):
@@ -67,6 +69,21 @@ def dummy_defaultBadFactory():
return u'b'
+ at provider(IInvariant)
+def dummy_invariant(data):
+ raise Invalid(u"Yikes! Invalid")
+
+
+ at provider(IInvariant)
+def dummy_invariant_prime(data):
+ return None
+
+
+def dummy_unmarkedInvariant(data):
+ """ lacks IInvariant marker """
+ return None
+
+
class TestUtils(unittest.TestCase):
def test_syncSchema(self):
-------------------------------------------------------------------------------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CHANGES.log
Type: application/octet-stream
Size: 22055 bytes
Desc: not available
URL: <http://lists.plone.org/pipermail/plone-testbot/attachments/20140530/84c1d859/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: build.log
Type: application/octet-stream
Size: 90589 bytes
Desc: not available
URL: <http://lists.plone.org/pipermail/plone-testbot/attachments/20140530/84c1d859/attachment-0003.obj>
More information about the Testbot
mailing list