use zope-testrunner for running all relevant tests => more Python3 fixes
This commit is contained in:
parent
33ab512b7f
commit
f1080df88b
11 changed files with 98 additions and 98 deletions
|
@ -47,4 +47,4 @@ Browser Views
|
|||
>>> page = Page(Document(), TestRequest())
|
||||
|
||||
>>> page()
|
||||
u'<!DOCTYPE ...>...<html ...>...</html>...'
|
||||
'<!DOCTYPE ...>...<html ...>...</html>...'
|
||||
|
|
|
@ -1,31 +1,11 @@
|
|||
#
|
||||
# Copyright (c) 2008 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.composer.layout.browser.liquid.default
|
||||
|
||||
"""
|
||||
Default layouts for the liquid skin.
|
||||
|
||||
$Id$
|
||||
""" Default layouts for the liquid skin.
|
||||
"""
|
||||
|
||||
from zope.app.pagetemplate import ViewPageTemplateFile
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
from zope import component
|
||||
from zope.interface import implements
|
||||
|
||||
from cybertools.browser.liquid import Liquid
|
||||
from cybertools.browser.renderer import RendererFactory
|
||||
|
|
|
@ -1,27 +1,9 @@
|
|||
#
|
||||
# Copyright (c) 2016 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.composer.layout.browser.view
|
||||
|
||||
"""
|
||||
Basic view classes for layout-based presentation.
|
||||
""" Basic view classes for layout-based presentation.
|
||||
"""
|
||||
|
||||
from zope import component
|
||||
from zope.interface import Interface, implements
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
from zope.app.pagetemplate import ViewPageTemplateFile
|
||||
from zope.app.security.interfaces import IUnauthenticatedPrincipal
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
Message Management
|
||||
==================
|
||||
|
||||
($Id$)
|
||||
|
||||
>>> from zope import component
|
||||
>>> from cybertools.composer.message.base import MessageManager, Message
|
||||
|
||||
|
@ -25,11 +23,11 @@ Message interpolation
|
|||
|
||||
>>> from cybertools.composer.message.instance import MessageTemplate
|
||||
>>> t = MessageTemplate(messageText)
|
||||
>>> print t.safe_substitute({
|
||||
>>> print(t.safe_substitute({
|
||||
... 'person.firstname': 'John', 'person.lastname': 'Smith',
|
||||
... '@@list_registrations_text': '0815: Python Introduction',
|
||||
... 'services': 'events',
|
||||
... 'footer': 'Regards, $sender'})
|
||||
... 'footer': 'Regards, $sender'}))
|
||||
Dear John Smith,
|
||||
You have been registered for the following events.
|
||||
0815: Python Introduction
|
||||
|
@ -42,11 +40,11 @@ Working with message instances
|
|||
>>> from cybertools.composer.message.instance import MessageInstance
|
||||
>>> mi = MessageInstance(None, manager.messages['feedback_text'], manager)
|
||||
>>> for key, value in mi.applyTemplate().items():
|
||||
... print key + ':', value
|
||||
... print(key + ':', value)
|
||||
url:
|
||||
subjectLine:
|
||||
text: Dear $person.firstname $person.lastname,
|
||||
You have been registered for the following events.
|
||||
$@@list_registrations_text
|
||||
Best regards, Jack
|
||||
<BLANKLINE>
|
||||
subjectLine:
|
||||
|
|
|
@ -12,11 +12,11 @@ Working with predefined schemas
|
|||
We start with setting up a schema with fields.
|
||||
|
||||
>>> serviceSchema = Schema(
|
||||
... Field(u'title', renderFactory=None),
|
||||
... Field(u'description'),
|
||||
... Field(u'start'),
|
||||
... Field(u'end'),
|
||||
... Field(u'capacity'),
|
||||
... Field('title', renderFactory=None),
|
||||
... Field('description'),
|
||||
... Field('start'),
|
||||
... Field('end'),
|
||||
... Field('capacity'),
|
||||
... )
|
||||
|
||||
For using a schema we need some class that we can use for creating
|
||||
|
@ -42,7 +42,7 @@ correct conversion of input data to context attributes.
|
|||
<...FormState object ...>
|
||||
|
||||
>>> srv.title, srv.description, srv.capacity
|
||||
(u'Service', u'', u'30')
|
||||
('Service', '', '30')
|
||||
|
||||
Field types
|
||||
-----------
|
||||
|
@ -62,7 +62,7 @@ Field types
|
|||
Dynamic default values
|
||||
----------------------
|
||||
|
||||
>>> idField = Field(u'id', default='user/title|string:???', defaultValueType='tales')
|
||||
>>> idField = Field('id', default='user/title|string:???', defaultValueType='tales')
|
||||
>>> idField.getDefaultValue()
|
||||
'???'
|
||||
|
||||
|
@ -70,27 +70,27 @@ Dynamic default values
|
|||
Creating a schema from an interface
|
||||
===================================
|
||||
|
||||
>>> from zope.interface import Interface, implements
|
||||
>>> from zope.interface import Interface, implementer
|
||||
>>> import zope.schema
|
||||
>>> from cybertools.composer.schema.factory import SchemaFactory
|
||||
>>> component.provideAdapter(SchemaFactory)
|
||||
|
||||
>>> class IPerson(Interface):
|
||||
... firstName = zope.schema.TextLine(title=u'First name')
|
||||
... lastName = zope.schema.TextLine(title=u'Last name')
|
||||
... age = zope.schema.Int(title=u'Age')
|
||||
... firstName = zope.schema.TextLine(title='First name')
|
||||
... lastName = zope.schema.TextLine(title='Last name')
|
||||
... age = zope.schema.Int(title='Age')
|
||||
|
||||
>>> class Person(object):
|
||||
... implements(IPerson)
|
||||
... def __init__(self, firstName=u'', lastName=u'', age=None):
|
||||
... def __init__(self, firstName='', lastName='', age=None):
|
||||
... self.firstName, self.lastName, self.age = firstName, lastName, age
|
||||
>>> Person = implementer(IPerson)(Person)
|
||||
|
||||
>>> from cybertools.composer.schema.interfaces import ISchemaFactory
|
||||
>>> factory = ISchemaFactory(Person())
|
||||
|
||||
>>> schema = factory(IPerson)
|
||||
>>> for f in schema.fields:
|
||||
... print f.name, f.title, f.fieldType
|
||||
... print(f.name, f.title, f.fieldType)
|
||||
firstName First name textline
|
||||
lastName Last name textline
|
||||
age Age number
|
||||
|
@ -109,7 +109,7 @@ Using a more specialized schema factory
|
|||
>>> factory = ISchemaFactory(Person())
|
||||
>>> schema = factory(IPerson)
|
||||
>>> for f in schema.fields:
|
||||
... print f.name, f.title, f.fieldType
|
||||
... print(f.name, f.title, f.fieldType)
|
||||
lastName Last name textline
|
||||
age Age number
|
||||
|
||||
|
@ -128,9 +128,9 @@ context object.
|
|||
>>> component.provideAdapter(NumberFieldInstance, name='number')
|
||||
|
||||
>>> from cybertools.composer.schema.instance import Instance
|
||||
>>> component.provideAdapter(Instance)
|
||||
>>> component.provideAdapter(Instance, adapts=(IPerson,))
|
||||
|
||||
>>> person = Person(u'John', u'Miller', 33)
|
||||
>>> person = Person('John', 'Miller', 33)
|
||||
|
||||
Note that the first name is not shown as we excluded it via the schema
|
||||
factory above. The age field is a number, but is shown here as a
|
||||
|
@ -140,7 +140,7 @@ data suitable for showing on an HTML form.
|
|||
>>> form = Form(person, TestRequest())
|
||||
>>> form.interface = IPerson
|
||||
>>> form.data
|
||||
{'lastName': u'Miller', 'age': '33'}
|
||||
{'lastName': 'Miller', 'age': '33'}
|
||||
|
||||
For editing we have to provide another instance adapter.
|
||||
|
||||
|
@ -165,7 +165,7 @@ Create a new object using a schema-based form
|
|||
>>> from cybertools.composer.schema.browser.form import CreateForm
|
||||
>>> container = dict()
|
||||
|
||||
>>> input = dict(lastName=u'Smith', age='28', action='update')
|
||||
>>> input = dict(lastName='Smith', age='28', action='update')
|
||||
>>> form = CreateForm(container, TestRequest(form=input))
|
||||
>>> form.interface = IPerson
|
||||
>>> form.factory = Person
|
||||
|
@ -174,23 +174,23 @@ Create a new object using a schema-based form
|
|||
>>> form.getName = lambda x: x.lastName.lower()
|
||||
|
||||
>>> form.data
|
||||
{'lastName': u'Smith', 'age': '28'}
|
||||
{'lastName': 'Smith', 'age': '28'}
|
||||
|
||||
>>> form.update()
|
||||
False
|
||||
|
||||
>>> p2 = container['smith']
|
||||
>>> p2.lastName, p2.age
|
||||
(u'Smith', 28)
|
||||
('Smith', 28)
|
||||
|
||||
Macros / renderers
|
||||
------------------
|
||||
|
||||
>>> fieldRenderers = form.fieldRenderers
|
||||
>>> sorted(fieldRenderers.keys())
|
||||
[u'field', u'field_spacer', u'fields', u'form', u'input_checkbox',
|
||||
u'input_date', u'input_dropdown', u'input_fileupload', u'input_html',
|
||||
u'input_list', u'input_password', u'input_textarea', u'input_textline']
|
||||
['field', 'field_spacer', 'fields', 'form', 'input_checkbox',
|
||||
'input_date', 'input_dropdown', 'input_fileupload', 'input_html',
|
||||
'input_list', 'input_password', 'input_textarea', 'input_textline']
|
||||
|
||||
|
||||
Special Field Types
|
||||
|
@ -202,15 +202,15 @@ Grids, Records, Key Tables
|
|||
>>> from cybertools.composer.schema.grid.field import KeyTableFieldInstance
|
||||
|
||||
>>> ktfield = Field('data')
|
||||
>>> ktfield.column_types = [zope.schema.Text(__name__='key', title=u'Key',),
|
||||
... zope.schema.Text(__name__='value', title=u'Value')]
|
||||
>>> ktfield.column_types = [zope.schema.Text(__name__='key', title='Key',),
|
||||
... zope.schema.Text(__name__='value', title='Value')]
|
||||
|
||||
>>> ktfi = KeyTableFieldInstance(ktfield)
|
||||
>>> ktfi.unmarshall([dict(key='0001', value='First row')])
|
||||
{u'0001': [u'First row']}
|
||||
{'0001': ['First row']}
|
||||
|
||||
>>> ktfi.marshall({u'0001': [u'First row']})
|
||||
[{'value': u'First row', 'key': u'0001'}]
|
||||
>>> ktfi.marshall({'0001': ['First row']})
|
||||
[{'key': '0001', 'value': 'First row'}]
|
||||
|
||||
Now with some real stuff, using a field instance that takes the column types
|
||||
from the context object of the edit form.
|
||||
|
@ -221,16 +221,16 @@ from the context object of the edit form.
|
|||
>>> component.provideAdapter(ContextBasedKeyTableFieldInstance, name='keytable')
|
||||
|
||||
>>> class IDataTable(Interface):
|
||||
... title = zope.schema.TextLine(title=u'Title', required=False)
|
||||
... columnNames = zope.schema.List(title=u'Column Names', required=False)
|
||||
... data = KeyTable(title=u'Data', required=False)
|
||||
... title = zope.schema.TextLine(title='Title', required=False)
|
||||
... columnNames = zope.schema.List(title='Column Names', required=False)
|
||||
... data = KeyTable(title='Data', required=False)
|
||||
>>> IDataTable['columnNames'].nostore = True
|
||||
|
||||
>>> class DataTable(object):
|
||||
... implements(IDataTable)
|
||||
... def __init__(self, title, columnNames):
|
||||
... self.title = title
|
||||
... self.columnNames = columnNames
|
||||
>>> DataTable = implementer(IDataTable)(DataTable)
|
||||
|
||||
>>> dt = DataTable('Account Types', ['identifier', 'label', 'info'])
|
||||
|
||||
|
@ -245,4 +245,4 @@ from the context object of the edit form.
|
|||
False
|
||||
|
||||
>>> dt.data
|
||||
{u'0001': [u'Standard', u'']}
|
||||
{'0001': ['Standard', '']}
|
||||
|
|
|
@ -66,13 +66,13 @@ class GridFieldInstance(ListFieldInstance):
|
|||
return result
|
||||
|
||||
def marshall(self, value):
|
||||
if isinstance(value, basestring):
|
||||
if isinstance(value, str):
|
||||
return value
|
||||
v = value or []
|
||||
for row in v:
|
||||
for fi in self.columnFieldInstances:
|
||||
vr = fi.marshall(row[fi.name])
|
||||
if isinstance(vr, basestring):
|
||||
if isinstance(vr, str):
|
||||
row[fi.name] = vr.replace('\n', '\\n').replace('"', '\\"')
|
||||
empty = {}
|
||||
for fi in self.columnFieldInstances:
|
||||
|
@ -136,9 +136,10 @@ class GridFieldInstance(ListFieldInstance):
|
|||
if idx is not None:
|
||||
fi.index = idx
|
||||
value = fi.unmarshall(row.get(fi.name) or u'')
|
||||
if isinstance(value, basestring):
|
||||
if isinstance(value, str):
|
||||
value = value.strip()
|
||||
if idx < cardinality:
|
||||
#if idx < cardinality:
|
||||
if cardinality is not None and (idx is None or idx < cardinality):
|
||||
item[fi.name] = value
|
||||
else:
|
||||
if fi.default is not None:
|
||||
|
|
|
@ -48,16 +48,16 @@ Now let's calculate the result for resp01.
|
|||
|
||||
>>> res = resp01.getResult()
|
||||
>>> for fi, score in res:
|
||||
... print fi.text, score
|
||||
... print(fi.text, score)
|
||||
fi03 4.1
|
||||
fi01 2.7
|
||||
fi02 0.7
|
||||
|
||||
>>> res = resp02.getResult()
|
||||
>>> for fi, score in res:
|
||||
... print fi.text, score
|
||||
... print(fi.text, score)
|
||||
fi03 4.0
|
||||
fi01 2.4
|
||||
fi01 2.4...
|
||||
|
||||
Grouped feedback items
|
||||
----------------------
|
||||
|
@ -70,12 +70,12 @@ Grouped feedback items
|
|||
|
||||
>>> res = resp01.getGroupedResult()
|
||||
>>> for r in res:
|
||||
... print r['feedback'].text, round(r['score'], 2), r['rank']
|
||||
... print(r['feedback'].text, round(r['score'], 2), r['rank'])
|
||||
fi02 0.58 1
|
||||
|
||||
>>> res = resp02.getGroupedResult()
|
||||
>>> for r in res:
|
||||
... print r['feedback'].text, round(r['score'], 2), r['rank']
|
||||
... print(r['feedback'].text, round(r['score'], 2), r['rank'])
|
||||
fi03 0.75 1
|
||||
|
||||
Team evaluation
|
||||
|
@ -89,5 +89,7 @@ Team evaluation
|
|||
|
||||
>>> teamData = resp01.getTeamResult([qugroup], [resp01, resp03])
|
||||
>>> teamData
|
||||
[{'group': ...}]
|
||||
|
||||
[{'average': 0.6666...}]
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ class Response(object):
|
|||
if qu.questionType not in (None, 'value_selection'):
|
||||
continue
|
||||
value = self.values.get(qu)
|
||||
if value is None or isinstance(value, basestring):
|
||||
if value is None or isinstance(value, str):
|
||||
continue
|
||||
answerRange = (qu.answerRange or
|
||||
self.questionnaire.defaultAnswerRange)
|
||||
|
|
6
cybertools/plugin/testing/load.py
Normal file
6
cybertools/plugin/testing/load.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
from cybertools.plugin.manage import loadModules
|
||||
|
||||
from cybertools.plugin.testing import mod1
|
||||
loadModules(mod1)
|
||||
|
|
@ -40,13 +40,13 @@ dependencies = [
|
|||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
test = ["pytest"]
|
||||
test = ["zope.testrunner"]
|
||||
|
||||
[tool.setuptools]
|
||||
packages = ["cybertools"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
addopts = "-vv"
|
||||
python_files = "test_standard.py" # default: run only `standard` tests
|
||||
#[tool.pytest.ini_options]
|
||||
#addopts = "-vv"
|
||||
#python_files = "test_standard.py" # default: run only `standard` tests
|
||||
# use .pytest.ini file with `python_files = test_*.py` to run all tests
|
||||
|
||||
|
|
31
runtests.sh
Executable file
31
runtests.sh
Executable file
|
@ -0,0 +1,31 @@
|
|||
# runtests.sh
|
||||
# run all currently relevant unit / doc tests
|
||||
|
||||
zope-testrunner --test-path=. \
|
||||
-s cybertools.brain \
|
||||
-s cybertools.browser \
|
||||
-s cybertools.catalog \
|
||||
-s cybertools.commerce \
|
||||
-s cybertools.composer \
|
||||
-s cybertools.container \
|
||||
-s cybertools.docgen \
|
||||
-s cybertools.external \
|
||||
-s cybertools.integrator -t \!bscw \
|
||||
-s cybertools.knowledge \
|
||||
-s cybertools.link \
|
||||
-s cybertools.media \
|
||||
-s cybertools.meta \
|
||||
-s cybertools.organize \
|
||||
-s cybertools.process \
|
||||
-s cybertools.relation \
|
||||
-s cybertools.reporter \
|
||||
-s cybertools.stateful \
|
||||
-s cybertools.storage -t \!pzope \
|
||||
-s cybertools.text \
|
||||
-s cybertools.tracking \
|
||||
-s cybertools.typology \
|
||||
-s cybertools.util \
|
||||
$*
|
||||
|
||||
#-s cybertools.view \
|
||||
#-s cybertools.wiki \
|
Loading…
Add table
Reference in a new issue