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:
parent
a66cd09817
commit
2b250fce37
2 changed files with 130 additions and 44 deletions
81
README.txt
81
README.txt
|
@ -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
93
tests/setup.py
Normal 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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue