Python3 fixes: standard tests OK
This commit is contained in:
parent
53be77b5b9
commit
ce7015b224
10 changed files with 61 additions and 110 deletions
|
@ -253,7 +253,7 @@ For testing we use some simple files from the tests directory:
|
|||
>>> from loops import tests
|
||||
>>> import os
|
||||
>>> path = os.path.join(*tests.__path__)
|
||||
>>> img.data = open(os.path.join(path, 'test_icon.png')).read()
|
||||
>>> img.data = open(os.path.join(path, 'test_icon.png'), 'rb').read()
|
||||
>>> img.getSize()
|
||||
381
|
||||
>>> img.getImageSize()
|
||||
|
@ -262,7 +262,7 @@ For testing we use some simple files from the tests directory:
|
|||
'image/png'
|
||||
|
||||
>>> pdf = Resource('A pdf File')
|
||||
>>> pdf.data = open(os.path.join(path, 'test.pdf')).read()
|
||||
>>> pdf.data = open(os.path.join(path, 'test.pdf'), 'rb').read()
|
||||
>>> pdf.getSize()
|
||||
25862
|
||||
>>> pdf.getImageSize()
|
||||
|
@ -661,9 +661,9 @@ Breadcrumbs
|
|||
>>> view = NodeView(m114, request)
|
||||
>>> request.annotations.setdefault('loops.view', {})['nodeView'] = view
|
||||
>>> view.breadcrumbs()
|
||||
[{'url': 'http://127.0.0.1/loops/views/m1', 'label': 'Menu'},
|
||||
{'url': 'http://127.0.0.1/loops/views/m1/m11', 'label': 'Zope'},
|
||||
{'url': 'http://127.0.0.1/loops/views/m1/m11/m114', 'label': ''}]
|
||||
[{'label': 'Menu', 'url': 'http://127.0.0.1/loops/views/m1'},
|
||||
{'label': 'Zope', 'url': 'http://127.0.0.1/loops/views/m1/m11'},
|
||||
{'label': '', 'url': 'http://127.0.0.1/loops/views/m1/m11/m114'}]
|
||||
|
||||
|
||||
End-user Forms and Special Views
|
||||
|
@ -714,7 +714,7 @@ been created during setup.
|
|||
|
||||
>>> form = CreateObjectForm(m112, TestRequest())
|
||||
>>> form.presetTypesForAssignment
|
||||
[{'token': 'loops:concept:customer', 'title': 'Customer'}]
|
||||
[{'title': 'Customer', 'token': 'loops:concept:customer'}]
|
||||
|
||||
If the node's target is a type concept we don't get any assignments because
|
||||
it does not make much sense to assign resources or other concepts as
|
||||
|
|
|
@ -1,35 +1,18 @@
|
|||
#
|
||||
# Copyright (c) 2015 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
|
||||
#
|
||||
# loops.browser.auth
|
||||
|
||||
"""
|
||||
Login, logout, unauthorized stuff.
|
||||
""" Login, logout, unauthorized stuff.
|
||||
"""
|
||||
|
||||
from zope.app.exception.browser.unauthorized import Unauthorized as DefaultUnauth
|
||||
from zope.app.security.interfaces import IAuthentication
|
||||
from zope.app.security.interfaces import ILogout, IUnauthenticatedPrincipal
|
||||
from zope.authentication.interfaces import IAuthentication
|
||||
from zope.authentication.interfaces import ILogout, IUnauthenticatedPrincipal
|
||||
from zope.browserpage import ViewPageTemplateFile
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
from zope import component
|
||||
from zope.interface import implements
|
||||
from zope.interface import implementer
|
||||
|
||||
from loops.browser.concept import ConceptView
|
||||
from loops.browser.node import NodeView
|
||||
from zope.app.pagetemplate import ViewPageTemplateFile
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
|
||||
|
||||
template = ViewPageTemplateFile('auth.pt')
|
||||
|
@ -57,9 +40,9 @@ class LoginForm(NodeView):
|
|||
return self
|
||||
|
||||
|
||||
@implementer(ILogout)
|
||||
class Logout(object):
|
||||
|
||||
implements(ILogout)
|
||||
|
||||
def __init__(self, context, request):
|
||||
self.context = context
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import os.path
|
||||
from zope.authentication.interfaces import IUnauthenticatedPrincipal
|
||||
from zope.browserpagge import ViewPageTemplateFile
|
||||
from zope.browserpage import ViewPageTemplateFile
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
from zope import component
|
||||
from zope.catalog.interfaces import ICatalog
|
||||
|
|
|
@ -187,6 +187,8 @@ class Concept(Contained, Persistent):
|
|||
usePredicateIndex=usePredicateIndex)
|
||||
if canListObject(r.second, noSecurityCheck) and
|
||||
IConcept.providedBy(r.second))
|
||||
if sort is None:
|
||||
return rels
|
||||
return sorted(rels, key=sort)
|
||||
|
||||
def getChildren(self, predicates=None, sort='default',
|
||||
|
|
|
@ -1,23 +1,6 @@
|
|||
#
|
||||
# Copyright (c) 2012 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
|
||||
#
|
||||
# loops.expert.query
|
||||
|
||||
"""
|
||||
Generic query functionality for retrieving stuff from a loops database.
|
||||
""" Generic query functionality for retrieving stuff from a loops database.
|
||||
"""
|
||||
|
||||
from BTrees.IIBTree import IITreeSet
|
||||
|
@ -25,7 +8,7 @@ from BTrees.IFBTree import IFBucket, IFBTree, IFTreeSet
|
|||
from BTrees.IOBTree import IOBucket, IOBTree
|
||||
from zope import interface, component
|
||||
from zope.component import adapts
|
||||
from zope.interface import implements, implementer
|
||||
from zope.interface import implementer
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
from zope.intid.interfaces import IIntIds
|
||||
|
||||
|
@ -91,10 +74,9 @@ def AnyKeyword(value):
|
|||
|
||||
# concept map queries
|
||||
|
||||
@implementer(IQuery)
|
||||
class ConceptMapTerm(Term):
|
||||
|
||||
implements(IQuery)
|
||||
|
||||
def __init__(self, concept, **kw):
|
||||
self.context = concept
|
||||
for k, v in kw.items():
|
||||
|
|
|
@ -6,8 +6,6 @@ This file documents and tests a bunch of facilities that support the
|
|||
loops framework, mostly provided by sub-packages of the cybertools
|
||||
package.
|
||||
|
||||
($Id$)
|
||||
|
||||
Let's first do some basic imports
|
||||
|
||||
>>> from zope import interface, component
|
||||
|
@ -22,48 +20,48 @@ Let's first do some basic imports
|
|||
>>> concepts, resources, views = t.setup()
|
||||
|
||||
>>> concepts['hasType'].title
|
||||
u'has Type'
|
||||
'has Type'
|
||||
|
||||
>>> loopsRoot = site['loops']
|
||||
|
||||
We also add some example concepts,
|
||||
|
||||
>>> from loops.concept import Concept
|
||||
>>> cc1 = Concept(u'Zope')
|
||||
>>> cc1 = Concept('Zope')
|
||||
>>> concepts['cc1'] = cc1
|
||||
>>> cc1.title
|
||||
u'Zope'
|
||||
'Zope'
|
||||
|
||||
>>> cc2 = Concept(u'Zope 3')
|
||||
>>> cc2 = Concept('Zope 3')
|
||||
>>> concepts['cc2'] = cc2
|
||||
>>> cc2.title
|
||||
u'Zope 3'
|
||||
'Zope 3'
|
||||
|
||||
resources,
|
||||
|
||||
>>> from loops.resource import Resource
|
||||
>>> file1 = resources['file1'] = Resource(u'A file')
|
||||
>>> file1 = resources['file1'] = Resource('A file')
|
||||
>>> file1.resourceType = concepts['file']
|
||||
|
||||
(note: the use of Document is deprecated)
|
||||
|
||||
>>> from loops.resource import Document
|
||||
>>> doc1 = Document(u'Zope Info')
|
||||
>>> doc1 = Document('Zope Info')
|
||||
>>> resources['doc1'] = doc1
|
||||
>>> doc1.title
|
||||
u'Zope Info'
|
||||
'Zope Info'
|
||||
|
||||
>>> img1 = resources['img1'] = Resource(u'An Image')
|
||||
>>> img1 = resources['img1'] = Resource('An Image')
|
||||
>>> img1.resourceType = concepts['file']
|
||||
|
||||
and nodes (in view space):
|
||||
|
||||
>>> from loops.view import Node
|
||||
>>> m1 = Node(u'Home')
|
||||
>>> m1 = Node('Home')
|
||||
>>> views['m1'] = m1
|
||||
>>> m1.nodeType = 'menu'
|
||||
|
||||
>>> m1p1 = Node(u'Page')
|
||||
>>> m1p1 = Node('Page')
|
||||
>>> m1['p1'] = m1p1
|
||||
>>> m1p1.nodeType = 'page'
|
||||
|
||||
|
@ -85,7 +83,7 @@ As we have not yet associated a type with one of our content objects we get
|
|||
>>> cc1_type.typeProvider is None
|
||||
True
|
||||
>>> cc1_type.title
|
||||
u'Unknown Type'
|
||||
'Unknown Type'
|
||||
>>> cc1_type.token
|
||||
'.unknown'
|
||||
|
||||
|
@ -107,9 +105,9 @@ So let's check the type of the type object:
|
|||
>>> type_type.typeProvider is typeObject
|
||||
True
|
||||
>>> type_type.title
|
||||
u'Type'
|
||||
'Type'
|
||||
>>> type_type.token
|
||||
u'.loops/concepts/type'
|
||||
'.loops/concepts/type'
|
||||
>>> type_type.tokenForSearch
|
||||
'loops:concept:type'
|
||||
>>> type_type.qualifiers
|
||||
|
@ -117,7 +115,7 @@ So let's check the type of the type object:
|
|||
|
||||
Now we register another type ('topic') and assign it to cc1:
|
||||
|
||||
>>> concepts['topic'] = Concept(u'Topic')
|
||||
>>> concepts['topic'] = Concept('Topic')
|
||||
>>> topic = concepts['topic']
|
||||
>>> topic.conceptType = typeObject
|
||||
>>> cc1.conceptType = topic
|
||||
|
@ -147,9 +145,9 @@ Now let's have a look at resources.
|
|||
>>> component.provideAdapter(LoopsType, (IResource,), IType)
|
||||
>>> file1_type = IType(file1)
|
||||
>>> file1_type.title
|
||||
u'File'
|
||||
'File'
|
||||
>>> file1_type.token
|
||||
u'.loops/concepts/file'
|
||||
'.loops/concepts/file'
|
||||
>>> file1_type.tokenForSearch
|
||||
'loops:resource:file'
|
||||
>>> file1_type.qualifiers
|
||||
|
@ -167,7 +165,7 @@ Now let's have a look at resources.
|
|||
|
||||
>>> doc1_type = IType(doc1)
|
||||
>>> doc1_type.title
|
||||
u'Document'
|
||||
'Document'
|
||||
>>> doc1_type.token
|
||||
'loops.resource.Document'
|
||||
>>> doc1_type.tokenForSearch
|
||||
|
@ -181,11 +179,11 @@ Now let's have a look at resources.
|
|||
|
||||
>>> img1_type = IType(img1)
|
||||
>>> img1_type.token
|
||||
u'.loops/concepts/file'
|
||||
'.loops/concepts/file'
|
||||
>>> img1_type.tokenForSearch
|
||||
'loops:resource:file'
|
||||
>>> img1_type.title
|
||||
u'File'
|
||||
'File'
|
||||
|
||||
Using the type machinery we can also specify options that may be used
|
||||
for controlling e.g. storage for external files.
|
||||
|
@ -194,8 +192,8 @@ for controlling e.g. storage for external files.
|
|||
>>> from loops.resource import FileAdapter
|
||||
>>> component.provideAdapter(FileAdapter, provides=IFile)
|
||||
|
||||
>>> extfile = concepts['extfile'] = Concept(u'External File')
|
||||
>>> ef1 = resources['ef1'] = Resource(u'Extfile #1')
|
||||
>>> extfile = concepts['extfile'] = Concept('External File')
|
||||
>>> ef1 = resources['ef1'] = Resource('Extfile #1')
|
||||
>>> ef1.resourceType = extfile
|
||||
>>> ef1_type = IType(ef1)
|
||||
>>> IType(ef1).options
|
||||
|
@ -208,7 +206,7 @@ for controlling e.g. storage for external files.
|
|||
>>> IType(ef1).options
|
||||
['dummy', 'storage:varsubdir', 'storage_parameters:extfiles']
|
||||
>>> IType(ef1).optionsDict
|
||||
{'default': ['dummy'], 'storage_parameters': 'extfiles', 'storage': 'varsubdir'}
|
||||
{'default': ['dummy'], 'storage': 'varsubdir', 'storage_parameters': 'extfiles'}
|
||||
|
||||
Can we find out somehow which types are available? This is the time to look
|
||||
for a type manager. This could be a utility; but in the loops package it
|
||||
|
@ -265,10 +263,10 @@ This is done by assigning this interface to topic_type.typeProvider,
|
|||
i.e. the 'topic' concept, via an adapter:
|
||||
|
||||
>>> class ITopic(Interface): pass
|
||||
>>> from zope.interface import implements
|
||||
>>> from zope.interface import implementer
|
||||
>>> class Topic(object):
|
||||
... implements(ITopic)
|
||||
... def __init__(self, context): pass
|
||||
>>> Topic = implementer(ITopic)(Topic)
|
||||
>>> from loops.interfaces import IConcept
|
||||
>>> component.provideAdapter(Topic, (IConcept,), ITopic)
|
||||
|
||||
|
@ -299,7 +297,7 @@ context object's type:
|
|||
>>> from loops.browser.common import BaseView
|
||||
>>> view = BaseView(cc1, TestRequest())
|
||||
>>> view.typeTitle
|
||||
u'Topic'
|
||||
'Topic'
|
||||
>>> view.typeInterface
|
||||
<InterfaceClass ...ITopic>
|
||||
>>> view.typeAdapter
|
||||
|
@ -321,7 +319,7 @@ been provided by the setup, but we have to register a corresponding adapter.
|
|||
|
||||
Next we need a concept of this type:
|
||||
|
||||
>>> simpleQuery = concepts['simpleQuery'] = Concept(u'Simple query')
|
||||
>>> simpleQuery = concepts['simpleQuery'] = Concept('Simple query')
|
||||
>>> simpleQuery.conceptType = query
|
||||
>>> sq_type = IType(simpleQuery)
|
||||
>>> sq_adapter = sq_type.typeInterface(simpleQuery)
|
||||
|
@ -426,7 +424,7 @@ Folders
|
|||
map.
|
||||
|
||||
>>> tFolder = addAndConfigureObject(concepts, Concept, 'folder',
|
||||
... title=u'Folder', conceptType=typeObject)
|
||||
... title='Folder', conceptType=typeObject)
|
||||
|
||||
Usually we want to create folders only in objects of a certain type,
|
||||
e.g. in a domain. So we activate the folder creation action by providing
|
||||
|
@ -444,7 +442,7 @@ If we now create a domain and set up a view on it it will provide the
|
|||
folder creation action.
|
||||
|
||||
>>> general = addAndConfigureObject(concepts, Concept, 'general',
|
||||
... title=u'General', conceptType=tDomain)
|
||||
... title='General', conceptType=tDomain)
|
||||
|
||||
>>> from loops.browser.concept import ConceptView
|
||||
>>> view = ConceptView(general, TestRequest())
|
||||
|
@ -454,7 +452,7 @@ folder creation action.
|
|||
Let's now create a folder.
|
||||
|
||||
>>> f01 = addAndConfigureObject(concepts, Concept, 'f01',
|
||||
... title=u'Test Folder', conceptType=tFolder)
|
||||
... title='Test Folder', conceptType=tFolder)
|
||||
|
||||
A folder should be associated with a FolderView that provides two actions
|
||||
for editing the folder and for creating a new subfolder.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
import unittest, doctest
|
||||
import warnings
|
||||
from zope.interface.verify import verifyClass
|
||||
from zope.intid.interfaces import IIntIds
|
||||
|
||||
|
@ -22,6 +23,7 @@ class Test(unittest.TestCase):
|
|||
"Basic tests for the loops package."
|
||||
|
||||
def testInterfaces(self):
|
||||
warnings.filterwarnings('ignore', category=ResourceWarning)
|
||||
verifyClass(ILoops, Loops)
|
||||
self.assertTrue(ILoops.providedBy(Loops()))
|
||||
verifyClass(IConcept, Concept)
|
||||
|
@ -45,7 +47,7 @@ def test_suite():
|
|||
return unittest.TestSuite((
|
||||
unittest.makeSuite(Test),
|
||||
doctest.DocFileSuite('../README.txt', optionflags=flags),
|
||||
#doctest.DocFileSuite('../helpers.txt', optionflags=flags),
|
||||
doctest.DocFileSuite('../helpers.txt', optionflags=flags),
|
||||
))
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -165,7 +165,7 @@ class ResourceType(LoopsType):
|
|||
@Lazy
|
||||
def title(self):
|
||||
cn = self.className
|
||||
return self.typeTitles.get(cn, unicode(cn))
|
||||
return self.typeTitles.get(cn, cn)
|
||||
|
||||
@Lazy
|
||||
def token(self):
|
||||
|
|
|
@ -1,28 +1,11 @@
|
|||
#
|
||||
# Copyright (c) 2015 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
|
||||
#
|
||||
# loops.versioning.browser
|
||||
|
||||
"""
|
||||
View classes for versioning.
|
||||
""" View classes for versioning.
|
||||
"""
|
||||
|
||||
from zope import interface, component
|
||||
from zope.app.pagetemplate import ViewPageTemplateFile
|
||||
from zope.app.security.interfaces import IUnauthenticatedPrincipal
|
||||
from zope.authentication.interfaces import IUnauthenticatedPrincipal
|
||||
from zope.browserpage import ViewPageTemplateFile
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
|
||||
from loops.browser.common import BaseView
|
||||
|
|
|
@ -16,8 +16,9 @@ dependencies = [
|
|||
"py-scopes",
|
||||
"markdown",
|
||||
"python-dotenv",
|
||||
"zope.app.renderer",
|
||||
"zope.app.authentication",
|
||||
"zope.app.exception",
|
||||
"zope.app.renderer",
|
||||
"zope.browsermenu",
|
||||
"zope.i18n",
|
||||
"zope.pluggableauth",
|
||||
|
|
Loading…
Add table
Reference in a new issue