starting doctests for constraint module
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2270 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
306d88b1eb
commit
2740774b3d
8 changed files with 149 additions and 7 deletions
|
@ -195,6 +195,15 @@ class Concept(Contained, Persistent):
|
||||||
# TODO (?): avoid duplicates
|
# TODO (?): avoid duplicates
|
||||||
registry.register(rel)
|
registry.register(rel)
|
||||||
|
|
||||||
|
def setChildren(self, predicate, concepts):
|
||||||
|
existing = self.getChildren([predicate])
|
||||||
|
for c in existing:
|
||||||
|
if c not in concepts:
|
||||||
|
self.deassignChild(c, [predicate])
|
||||||
|
for c in concepts:
|
||||||
|
if c not in existing:
|
||||||
|
self.assignChild(c, predicate)
|
||||||
|
|
||||||
def assignParent(self, concept, predicate=None, order=0, relevance=1.0):
|
def assignParent(self, concept, predicate=None, order=0, relevance=1.0):
|
||||||
concept.assignChild(self, predicate, order, relevance)
|
concept.assignChild(self, predicate, order, relevance)
|
||||||
|
|
||||||
|
|
|
@ -6,20 +6,49 @@ loops - Linked Objects for Organization and Processing Services
|
||||||
|
|
||||||
>>> from zope import component
|
>>> from zope import component
|
||||||
>>> from zope.traversing.api import getName
|
>>> from zope.traversing.api import getName
|
||||||
|
>>> from loops.common import adapted
|
||||||
|
>>> from loops.concept import Concept
|
||||||
|
>>> from loops.setup import addAndConfigureObject
|
||||||
|
|
||||||
Let's set up a loops site with basic and example concepts and resources.
|
Let's set up a loops site with basic and example concepts and resources.
|
||||||
|
|
||||||
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
||||||
>>> site = placefulSetUp(True)
|
>>> site = placefulSetUp(True)
|
||||||
|
|
||||||
>>> from loops.tests.setup import TestSite
|
>>> from loops.constraint.testsetup import TestSite
|
||||||
>>> t = TestSite(site)
|
>>> t = TestSite(site)
|
||||||
>>> concepts, resources, views = t.setup()
|
>>> concepts, resources, views = t.setup()
|
||||||
|
|
||||||
|
>>> tType = concepts.getTypeConcept()
|
||||||
|
|
||||||
|
|
||||||
Constraints - Restrict Predicates and Types for Concept and Resource Assignments
|
Constraints - Restrict Predicates and Types for Concept and Resource Assignments
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
>>> from loops.constraint.base import StaticConstraint
|
We create a person type and an institution type and a corresponding
|
||||||
>>> component.provideAdapter(StaticConstraint)
|
predicate.
|
||||||
|
|
||||||
|
>>> tPerson = addAndConfigureObject(concepts, Concept, 'person',
|
||||||
|
... title='Person', conceptType=tType)
|
||||||
|
>>> tInstitution = addAndConfigureObject(concepts, Concept, 'institution',
|
||||||
|
... title='Institution', conceptType=tType)
|
||||||
|
>>> tPredicate = concepts.getPredicateType()
|
||||||
|
>>> isEmployedBy = addAndConfigureObject(concepts, Concept, 'isemployedby',
|
||||||
|
... title='is Employed by', conceptType=tPredicate)
|
||||||
|
|
||||||
|
The static constraint concept type has already been created during setup.
|
||||||
|
We create a simple constraint that
|
||||||
|
|
||||||
|
>>> tStaticConstraint = concepts['staticconstraint']
|
||||||
|
>>> cstr01 = addAndConfigureObject(concepts, Concept, 'cstr01',
|
||||||
|
... title='Demo Constraint', conceptType=tStaticConstraint)
|
||||||
|
|
||||||
|
>>> aCstr01 = adapted(cstr01)
|
||||||
|
>>> aCstr01.predicates = [isEmployedBy]
|
||||||
|
>>> aCstr01.types = [tInstitution]
|
||||||
|
|
||||||
|
We can now use this constraint to control the parent concepts a person
|
||||||
|
may be assigned to.
|
||||||
|
|
||||||
|
>>> from loops.constraint.base import hasConstraint
|
||||||
|
>>> tPerson.assignParent(cstr01, hasConstraint)
|
||||||
|
|
|
@ -34,6 +34,11 @@ from loops.type import TypeInterfaceSourceList
|
||||||
|
|
||||||
TypeInterfaceSourceList.typeInterfaces += (IStaticConstraint,)
|
TypeInterfaceSourceList.typeInterfaces += (IStaticConstraint,)
|
||||||
|
|
||||||
|
isPredicate = 'ispredicateforconstraint'
|
||||||
|
isType = 'istypeforconstraint'
|
||||||
|
hasConstraint = 'hasconstraint'
|
||||||
|
hasChildConstraint = 'haschildconstraint'
|
||||||
|
|
||||||
|
|
||||||
class StaticConstraint(AdapterBase):
|
class StaticConstraint(AdapterBase):
|
||||||
|
|
||||||
|
@ -43,13 +48,13 @@ class StaticConstraint(AdapterBase):
|
||||||
implements(IStaticConstraint)
|
implements(IStaticConstraint)
|
||||||
|
|
||||||
def getPredicates(self):
|
def getPredicates(self):
|
||||||
return getattr(self.context, '_predicates', [])
|
return self.context.getChildren([isPredicate])
|
||||||
def setPredicates(self, value):
|
def setPredicates(self, value):
|
||||||
self.context._predicates = value
|
self.context.setChildren(isPredicate, value)
|
||||||
predicates = property(getPredicates, setPredicates)
|
predicates = property(getPredicates, setPredicates)
|
||||||
|
|
||||||
def getTypes(self):
|
def getTypes(self):
|
||||||
return getattr(self.context, '_types', [])
|
return self.context.getChildren([isType])
|
||||||
def setTypes(self, value):
|
def setTypes(self, value):
|
||||||
self.context._types = value
|
self.context.setChildren(isType, value)
|
||||||
types = property(getTypes, setTypes)
|
types = property(getTypes, setTypes)
|
||||||
|
|
|
@ -15,4 +15,7 @@
|
||||||
set_schema="loops.constraint.interfaces.IStaticConstraint" />
|
set_schema="loops.constraint.interfaces.IStaticConstraint" />
|
||||||
</zope:class>
|
</zope:class>
|
||||||
|
|
||||||
|
<!--<zope:adapter factory="loops.constraint.setup.SetupManager"
|
||||||
|
name="constraint" />-->
|
||||||
|
|
||||||
</configure>
|
</configure>
|
||||||
|
|
53
constraint/setup.py
Normal file
53
constraint/setup.py
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006 Helmut Merz helmutm@cy55.de
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Automatic setup of a loops site for the constraint package.
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
"""
|
||||||
|
|
||||||
|
from zope.component import adapts
|
||||||
|
from zope.interface import implements, Interface
|
||||||
|
|
||||||
|
from loops.concept import Concept
|
||||||
|
from loops.constraint.interfaces import IStaticConstraint
|
||||||
|
from loops.constraint.base import isPredicate, isType
|
||||||
|
from loops.constraint.base import hasConstraint, hasChildConstraint
|
||||||
|
from loops.setup import SetupManager as BaseSetupManager
|
||||||
|
|
||||||
|
|
||||||
|
class SetupManager(BaseSetupManager):
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
concepts = self.context.getConceptManager()
|
||||||
|
type = concepts.getTypeConcept()
|
||||||
|
predicate = concepts['predicate']
|
||||||
|
# type concepts:
|
||||||
|
constraint = self.addAndConfigureObject(concepts, Concept,
|
||||||
|
'staticconstraint', title=u'Constraint',
|
||||||
|
conceptType=type, typeInterface=IStaticConstraint)
|
||||||
|
self.addObject(concepts, Concept, isPredicate,
|
||||||
|
title=u'is Predicate for Constraint', conceptType=predicate)
|
||||||
|
self.addObject(concepts, Concept, isType,
|
||||||
|
title=u'is Type for Constraint', conceptType=predicate)
|
||||||
|
self.addObject(concepts, Concept, hasConstraint,
|
||||||
|
title=u'has Constraint', conceptType=predicate)
|
||||||
|
self.addObject(concepts, Concept, hasChildConstraint,
|
||||||
|
title=u'has Child Constraint', conceptType=predicate)
|
||||||
|
|
32
constraint/testsetup.py
Normal file
32
constraint/testsetup.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
"""
|
||||||
|
Set up a loops site for testing.
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
from zope import component
|
||||||
|
from zope.app.catalog.interfaces import ICatalog
|
||||||
|
from zope.app.catalog.field import FieldIndex
|
||||||
|
|
||||||
|
from loops import util
|
||||||
|
from loops.concept import Concept
|
||||||
|
from loops.constraint.base import StaticConstraint
|
||||||
|
from loops.constraint.setup import SetupManager
|
||||||
|
from loops.setup import addAndConfigureObject
|
||||||
|
from loops.tests.setup import TestSite as BaseTestSite
|
||||||
|
|
||||||
|
|
||||||
|
class TestSite(BaseTestSite):
|
||||||
|
|
||||||
|
def __init__(self, site):
|
||||||
|
self.site = site
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
component.provideAdapter(SetupManager, name='constraint')
|
||||||
|
concepts, resources, views = self.baseSetup()
|
||||||
|
|
||||||
|
component.provideAdapter(StaticConstraint)
|
||||||
|
|
||||||
|
return concepts, resources, views
|
||||||
|
|
|
@ -153,6 +153,14 @@ class IConcept(IConceptSchema, ILoopsObject, IPotentialTarget):
|
||||||
optionally restricting them to the predicates given.
|
optionally restricting them to the predicates given.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def setChildren(predicate, concepts):
|
||||||
|
""" A convenience method for adding and removing a set of child
|
||||||
|
relations in one call. The relations with the predicate given
|
||||||
|
that already point to one of the concepts given as the second
|
||||||
|
argument are kept unchanged, new ones are assigned, and existing
|
||||||
|
ones not present in the concepts list are removed.
|
||||||
|
"""
|
||||||
|
|
||||||
def getResources(predicates=None):
|
def getResources(predicates=None):
|
||||||
""" Return a sequence of resources assigned to self,
|
""" Return a sequence of resources assigned to self,
|
||||||
optionally restricted to the predicates given.
|
optionally restricted to the predicates given.
|
||||||
|
|
3
setup.py
3
setup.py
|
@ -99,6 +99,9 @@ class SetupManager(object):
|
||||||
def addObject(self, container, class_, name, **kw):
|
def addObject(self, container, class_, name, **kw):
|
||||||
return addObject(container, class_, name, **kw)
|
return addObject(container, class_, name, **kw)
|
||||||
|
|
||||||
|
def addAndConfigureObject(self, container, class_, name, **kw):
|
||||||
|
return addAndConfigureObject(container, class_, name, **kw)
|
||||||
|
|
||||||
|
|
||||||
def addObject(container, class_, name, **kw):
|
def addObject(container, class_, name, **kw):
|
||||||
if name in container:
|
if name in container:
|
||||||
|
|
Loading…
Add table
Reference in a new issue