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:
helmutm 2007-12-23 21:01:45 +00:00
parent 306d88b1eb
commit 2740774b3d
8 changed files with 149 additions and 7 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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
View 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
View 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

View file

@ -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.

View file

@ -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: