provide a common test site setup for doctests

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1681 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-04-10 14:55:59 +00:00
parent a66cd09817
commit 2b250fce37
2 changed files with 130 additions and 44 deletions

View file

@ -31,11 +31,18 @@ Let's start with creating a few example concepts, putting them in a
top-level loops container and a concept manager: top-level loops container and a concept manager:
>>> from loops import Loops >>> from loops import Loops
>>> loopsRoot = site['loops'] = Loops() >>> from loops.tests.setup import TestSite
>>> t = TestSite(site)
>>> concepts, resources, views = t.setup()
>>> #sorted(concepts)
>>> #sorted(resources)
>>> len(concepts) + len(resources)
14
>>> loopsRoot = site['loops']
>>> from loops.concept import ConceptManager, Concept >>> from loops.concept import ConceptManager, Concept
>>> loopsRoot['concepts'] = ConceptManager()
>>> concepts = loopsRoot['concepts']
>>> cc1 = Concept() >>> cc1 = Concept()
>>> concepts['cc1'] = cc1 >>> concepts['cc1'] = cc1
>>> cc1.title >>> cc1.title
@ -50,21 +57,11 @@ top-level loops container and a concept manager:
Now we want to relate the second concept to the first one. Now we want to relate the second concept to the first one.
In order to do this we first have to provide a relation registry. For
testing we use a simple dummy implementation.
>>> from cybertools.relation.tests import IntIdsStub
>>> component.provideUtility(IntIdsStub())
>>> from cybertools.relation.interfaces import IRelationRegistry
>>> from cybertools.relation.registry import DummyRelationRegistry
>>> component.provideUtility(DummyRelationRegistry())
>>> from cybertools.relation.registry import RelationRegistry >>> from cybertools.relation.registry import RelationRegistry
As relationships are based on predicates that are themselves concepts we As relationships are based on predicates that are themselves concepts we
also need a default predicate concept; the default name for this is also need a default predicate concept; the default name for this is
'standard'. 'standard'. It has already been created during setup.
>>> concepts['standard'] = Concept(u'subconcept')
Now we can assign the concept c2 as a child to c1 (using the standard Now we can assign the concept c2 as a child to c1 (using the standard
ConceptRelation): ConceptRelation):
@ -88,8 +85,6 @@ relation to a special kind of concept object with the magic name 'type'.
This type object is its own type. The type relations themselves are of This type object is its own type. The type relations themselves are of
a special predicate 'hasType'. a special predicate 'hasType'.
>>> concepts['hasType'] = Concept(u'has type')
>>> concepts['type'] = Concept(u'Type')
>>> typeObject = concepts['type'] >>> typeObject = concepts['type']
>>> typeObject.setConceptType(typeObject) >>> typeObject.setConceptType(typeObject)
>>> typeObject.getConceptType().title >>> typeObject.getConceptType().title
@ -127,16 +122,10 @@ type manager.
>>> from loops.concept import ConceptTypeSourceList >>> from loops.concept import ConceptTypeSourceList
>>> types = ConceptTypeSourceList(cc1) >>> types = ConceptTypeSourceList(cc1)
>>> sorted(t.title for t in types) >>> sorted(t.title for t in types)
[u'Topic', u'Type', u'Unknown Type'] [u'Domain', u'Predicate', u'Query', u'Topic', u'Type', u'Unknown Type']
Using a PredicateSourceList we can retrieve a list of the available Using a PredicateSourceList we can retrieve a list of the available
predicates. In order for this to work we first have to assign our predicates predicates.
a special concept type.
>>> concepts['predicate'] = Concept(u'Predicate')
>>> predicate = concepts['predicate']
>>> concepts['hasType'].conceptType = predicate
>>> concepts['standard'].conceptType = predicate
>>> from loops.concept import PredicateSourceList >>> from loops.concept import PredicateSourceList
>>> predicates = PredicateSourceList(cc1) >>> predicates = PredicateSourceList(cc1)
@ -145,7 +134,7 @@ Note that the 'hasType' predicate is suppressed from this list as the
corresponding relation is only assigned via the conceptType attribute: corresponding relation is only assigned via the conceptType attribute:
>>> sorted(t.title for t in predicates) >>> sorted(t.title for t in predicates)
[u'subconcept'] [u'subobject']
Concept Views Concept Views
------------- -------------
@ -206,11 +195,15 @@ types and predicates.
>>> component.provideAdapter(LoopsTerms, (IIterableSource, IBrowserRequest), ITerms) >>> component.provideAdapter(LoopsTerms, (IIterableSource, IBrowserRequest), ITerms)
>>> sorted((t.title, t.token) for t in view.conceptTypes()) >>> sorted((t.title, t.token) for t in view.conceptTypes())
[(u'Topic', '.loops/concepts/topic'), (u'Type', '.loops/concepts/type'), [(u'Domain', '.loops/concepts/domain'),
(u'Unknown Type', '.loops/concepts/unknown')] (u'Predicate', '.loops/concepts/predicate'),
(u'Query', '.loops/concepts/query'),
(u'Topic', '.loops/concepts/topic'),
(u'Type', '.loops/concepts/type'),
(u'Unknown Type', '.loops/concepts/unknown')]
>>> sorted((t.title, t.token) for t in view.predicates()) >>> sorted((t.title, t.token) for t in view.predicates())
[(u'subconcept', '.loops/concepts/standard')] [(u'subobject', '.loops/concepts/standard')]
Index attributes adapter Index attributes adapter
------------------------ ------------------------
@ -232,8 +225,6 @@ Resources and what they have to do with Concepts
We first need a resource manager: We first need a resource manager:
>>> from loops.resource import ResourceManager, Resource >>> from loops.resource import ResourceManager, Resource
>>> loopsRoot['resources'] = ResourceManager()
>>> resources = loopsRoot['resources']
A common type of resource is a document: A common type of resource is a document:
@ -316,6 +307,9 @@ Index attributes adapter
>>> from loops.resource import IndexAttributes >>> from loops.resource import IndexAttributes
>>> from loops.type import LoopsType >>> from loops.type import LoopsType
>>> component.provideAdapter(LoopsType) >>> component.provideAdapter(LoopsType)
>>> from loops.resource import FileAdapter
>>> from loops.interfaces import IFile
>>> component.provideAdapter(FileAdapter, provides=IFile)
>>> idx = IndexAttributes(doc1) >>> idx = IndexAttributes(doc1)
>>> idx.text() >>> idx.text()
u'' u''
@ -338,15 +332,13 @@ of a site only see views or nodes but never concepts or resources directly;
the views or nodes, however, present informations coming from the concepts the views or nodes, however, present informations coming from the concepts
or resources they are related to. or resources they are related to.
We first need a view manager: The view manager has already been created during setup.
>>> from loops.view import ViewManager, Node >>> from loops.view import ViewManager, Node
>>> from zope.security.checker import NamesChecker, defineChecker >>> from zope.security.checker import NamesChecker, defineChecker
>>> nodeChecker = NamesChecker(('body', 'title',)) >>> nodeChecker = NamesChecker(('body', 'title',))
>>> defineChecker(Node, nodeChecker) >>> defineChecker(Node, nodeChecker)
>>> views = loopsRoot['views'] = ViewManager()
The view space is typically built up with nodes; a node may be a top-level The view space is typically built up with nodes; a node may be a top-level
menu that may contain other nodes as menu or content items: menu that may contain other nodes as menu or content items:
@ -496,13 +488,15 @@ view; these views we have to provide as multi-adapters:
>>> form = {'action': 'create', 'create.title': 'New Resource', >>> form = {'action': 'create', 'create.title': 'New Resource',
... 'create.type': 'loops.resource.MediaAsset',} ... 'create.type': 'loops.resource.MediaAsset',}
>>> view = ConfigureView(m111, TestRequest(form = form)) >>> view = ConfigureView(m111, TestRequest(form = form))
>>> sorted((t.token, t.title) for t in view.targetTypes()) >>> tt = view.targetTypes()
[('.loops/concepts/topic', u'Topic'), ('.loops/concepts/type', u'Type'), >>> len(tt)
('.loops/concepts/unknown', u'Unknown Type')] 9
>>> sorted((t.token, t.title) for t in view.targetTypes())[0]
('.loops/concepts/domain', u'Domain')
>>> view.update() >>> view.update()
True True
>>> sorted(resources.keys()) >>> sorted(resources.keys())
[u'doc1', u'm1.m11.m111'] [u'd001.txt', u'd002.txt', u'd003.txt', u'doc1', u'm1.m11.m111']
>>> view.target.title, view.target.token >>> view.target.title, view.target.token
('New Resource', '.loops/resources/m1.m11.m111') ('New Resource', '.loops/resources/m1.m11.m111')
@ -625,9 +619,10 @@ preset concepts, e.g. depending on the target of the current node:
There also may be preset concept types that directly provide lists of There also may be preset concept types that directly provide lists of
concepts to select from. concepts to select from.
To show this let's start with a new type, the customer type. To show this let's start with a new type, the customer type, that has
been created during setup.
>>> customer = concepts['customer'] = Concept('Customer') >>> customer = concepts['customer']
>>> customer.conceptType = concepts.getTypeConcept() >>> customer.conceptType = concepts.getTypeConcept()
>>> from loops.type import ConceptType, TypeConcept >>> from loops.type import ConceptType, TypeConcept
>>> custType = TypeConcept(customer) >>> custType = TypeConcept(customer)
@ -642,7 +637,7 @@ To show this let's start with a new type, the customer type.
>>> form = CreateObjectForm(m112, TestRequest()) >>> form = CreateObjectForm(m112, TestRequest())
>>> form.presetTypesForAssignment >>> form.presetTypesForAssignment
[{'token': 'loops:concept:customer', 'title': 'Customer'}] [{'token': 'loops:concept:customer', 'title': u'Customer'}]
OK, so much about the form - now we want to create a new object based OK, so much about the form - now we want to create a new object based
on data provided in this form: on data provided in this form:
@ -652,9 +647,7 @@ on data provided in this form:
>>> from loops.resource import NoteAdapter >>> from loops.resource import NoteAdapter
>>> component.provideAdapter(TypeConcept) >>> component.provideAdapter(TypeConcept)
>>> component.provideAdapter(NoteAdapter, provides=INote) >>> component.provideAdapter(NoteAdapter, provides=INote)
>>> note_tc = concepts['note'] = Concept('Note') >>> note_tc = concepts['note']
>>> note_tc.conceptType = typeObject
>>> ITypeConcept(note_tc).typeInterface = INote
>>> component.provideAdapter(NameChooser) >>> component.provideAdapter(NameChooser)
>>> request = TestRequest(form={'form.title': u'Test Note', >>> request = TestRequest(form={'form.title': u'Test Note',
@ -747,7 +740,7 @@ target object's view here:
[<loops.browser.common.Action object ...>] [<loops.browser.common.Action object ...>]
>>> action = view.virtualTarget.getActions()[0] >>> action = view.virtualTarget.getActions()[0]
>>> action.url >>> action.url
'http://127.0.0.1/loops/views/m1/m11/m111/.target19' 'http://127.0.0.1/loops/views/m1/m11/m111/.target57'
Import/Export Import/Export

93
tests/setup.py Normal file
View file

@ -0,0 +1,93 @@
"""
Set up a loops site for testing.
$Id$
"""
from zope import component
from zope.app.catalog.catalog import Catalog
from zope.app.catalog.interfaces import ICatalog
from zope.app.catalog.field import FieldIndex
from zope.app.catalog.text import TextIndex
from cybertools.relation.tests import IntIdsStub
from cybertools.relation.registry import RelationRegistry
from cybertools.relation.interfaces import IRelationRegistry
from cybertools.relation.registry import IndexableRelationAdapter
from cybertools.typology.interfaces import IType
from loops import Loops
from loops import util
from loops.interfaces import IIndexAttributes
from loops.concept import Concept
from loops.concept import IndexAttributes as ConceptIndexAttributes
from loops.resource import Resource
from loops.resource import IndexAttributes as ResourceIndexAttributes
from loops.setup import SetupManager, addObject
from loops.type import ConceptType, ResourceType, TypeConcept
class TestSite(object):
def __init__(self, site):
self.site = site
def baseSetup(self):
site = self.site
component.provideUtility(IntIdsStub())
relations = RelationRegistry()
relations.setupIndexes()
component.provideUtility(relations, IRelationRegistry)
component.provideAdapter(IndexableRelationAdapter)
component.provideAdapter(ConceptType)
component.provideAdapter(ResourceType)
component.provideAdapter(TypeConcept)
catalog = self.catalog = Catalog()
component.provideUtility(catalog, ICatalog)
catalog['loops_title'] = TextIndex('title', IIndexAttributes, True)
catalog['loops_text'] = TextIndex('text', IIndexAttributes, True)
catalog['loops_type'] = FieldIndex('tokenForSearch', IType, False)
component.provideAdapter(ConceptIndexAttributes)
component.provideAdapter(ResourceIndexAttributes)
loopsRoot = site['loops'] = Loops()
setup = SetupManager(loopsRoot)
concepts, resources, views = setup.setup()
return concepts, resources, views
def setup(self):
concepts, resources, views = self.baseSetup()
catalog = component.getUtility(ICatalog)
tType = concepts.getTypeConcept()
tDomain = concepts['domain']
tTextDocument = concepts['textdocument']
tFile = concepts['file']
tCustomer = addObject(concepts, Concept, 'customer', title=u'Customer',
type=tType)
dProjects = addObject(concepts, Concept, 'projects',
title=u'Project Domain', type=tDomain)
tCustomer.assignParent(dProjects)
d001 = addObject(resources, Resource, 'd001.txt',
title=u'Doc 001', type=tTextDocument)
d002 = addObject(resources, Resource, 'd002.txt',
title=u'Doc 002', type=tTextDocument)
d003 = addObject(resources, Resource, 'd003.txt',
title=u'Doc 003', type=tTextDocument)
self.indexAll(concepts, resources)
return concepts, resources, views
def indexAll(self, concepts, resources):
for c in concepts.values():
self.catalog.index_doc(int(util.getUidForObject(c)), c)
for r in resources.values():
self.catalog.index_doc(int(util.getUidForObject(r)), r)