--- a/_exceptions.py Thu Sep 23 23:28:58 2010 +0200
+++ b/_exceptions.py Wed Sep 29 16:16:32 2010 +0200
@@ -130,14 +130,20 @@
"""
class NoSelectableObject(RegistryException):
- """some views with the given vid have been found but no
- one is applicable to the result set
- """
+ """raised when no appobject is selectable for a given context."""
+ def __init__(self, args, kwargs, appobjects):
+ self.args = args
+ self.kwargs = kwargs
+ self.appobjects = appobjects
+
+ def __str__(self):
+ return ('args: %s, kwargs: %s\ncandidates: %s'
+ % (self.args, self.kwargs.keys(), self.appobjects))
+
class UnknownProperty(RegistryException):
"""property found in database but unknown in registry"""
-
# query exception #############################################################
class QueryError(CubicWebRuntimeError):
--- a/devtools/cwwindmill.py Thu Sep 23 23:28:58 2010 +0200
+++ b/devtools/cwwindmill.py Wed Sep 29 16:16:32 2010 +0200
@@ -26,10 +26,9 @@
import os, os.path as osp
import sys
-import unittest
# imported by default to simplify further import statements
-from logilab.common.testlib import unittest_main
+from logilab.common.testlib import TestCase, unittest_main
import windmill
from windmill.dep import functest
@@ -45,7 +44,7 @@
unittestreporter = UnitTestReporter()
functest.reports.register_reporter(unittestreporter)
-class WindmillUnitTestCase(unittest.TestCase):
+class WindmillUnitTestCase(TestCase):
def setUp(self):
windmill.stdout, windmill.stdin = sys.stdout, sys.stdin
from windmill.bin.admin_lib import configure_global_settings, setup
--- a/devtools/devctl.py Thu Sep 23 23:28:58 2010 +0200
+++ b/devtools/devctl.py Wed Sep 29 16:16:32 2010 +0200
@@ -26,8 +26,7 @@
# completion). So import locally in command helpers.
import sys
from datetime import datetime
-from os import mkdir, chdir
-from os.path import join, exists, abspath, basename, normpath, split, isdir
+from os import mkdir, chdir, listdir, path as osp
from warnings import warn
from logilab.common import STD_BLACKLIST
@@ -35,8 +34,8 @@
from cubicweb.__pkginfo__ import version as cubicwebversion
from cubicweb import CW_SOFTWARE_ROOT as BASEDIR, BadCommandUsage
from cubicweb.cwctl import CWCTL
-from cubicweb.toolsutils import (SKEL_EXCLUDE, Command,
- copy_skeleton, underline_title)
+from cubicweb.toolsutils import (SKEL_EXCLUDE, Command, copy_skeleton,
+ underline_title)
from cubicweb.web.webconfig import WebConfiguration
from cubicweb.server.serverconfig import ServerConfiguration
@@ -102,7 +101,7 @@
"""
from cubicweb.cwvreg import CubicWebVRegistry
if cubedir:
- cube = split(cubedir)[-1]
+ cube = osp.split(cubedir)[-1]
config = DevConfiguration(cube)
depcubes = list(config._cubes)
depcubes.remove(cube)
@@ -125,7 +124,8 @@
from cubicweb.web import uicfg
from cubicweb.schema import META_RTYPES, SYSTEM_RTYPES, CONSTRAINTS
no_context_rtypes = META_RTYPES | SYSTEM_RTYPES
- w('# schema pot file, generated on %s\n' % datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
+ w('# schema pot file, generated on %s\n'
+ % datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
w('# \n')
w('# singular and plural forms for each entity type\n')
w('\n')
@@ -177,7 +177,8 @@
add_msg(w, str(tschema),
'inlined:%s.%s.%s' % (etype, rschema, role))
if appearsin_addmenu.etype_get(eschema, rschema, role, tschema):
- if libconfig is not None and libappearsin_addmenu.etype_get(eschema, rschema, role, tschema):
+ if libconfig is not None and libappearsin_addmenu.etype_get(
+ eschema, rschema, role, tschema):
if eschema in libschema and tschema in libschema:
continue
if role == 'subject':
@@ -200,7 +201,8 @@
for rschema in sorted(schema.relations()):
rtype = rschema.type
if rtype not in libschema:
- # bw compat, necessary until all translation of relation are done properly...
+ # bw compat, necessary until all translation of relation are done
+ # properly...
add_msg(w, rtype)
if rschema.description and rschema.description not in done:
done.add(rschema.description)
@@ -222,7 +224,8 @@
if not objschema in libobjects:
add_msg(w, '%s_object' % rtype, objschema.type)
if rtype not in libschema:
- # bw compat, necessary until all translation of relation are done properly...
+ # bw compat, necessary until all translation of relation are
+ # done properly...
add_msg(w, '%s_object' % rtype)
for objid in _iter_vreg_objids(vreg, vregdone):
add_msg(w, '%s_description' % objid)
@@ -246,8 +249,6 @@
break
-LANGS = ('en', 'fr', 'es')
-I18NDIR = join(BASEDIR, 'i18n')
DEFAULT_POT_HEAD = r'''msgid ""
msgstr ""
"Project-Id-Version: cubicweb %s\n"
@@ -262,6 +263,11 @@
''' % cubicwebversion
+def cw_languages():
+ for fname in listdir(osp.join(WebConfiguration.i18n_lib_dir())):
+ if fname.endswith('.po'):
+ yield osp.splitext(fname)[0]
+
class UpdateCubicWebCatalogCommand(Command):
"""Update i18n catalogs for cubicweb library.
@@ -270,11 +276,10 @@
files to add translations of newly added messages.
"""
name = 'i18ncubicweb'
+ min_args = max_args = 0
def run(self, args):
"""run the command with its specific arguments"""
- if args:
- raise BadCommandUsage('Too many arguments')
import shutil
import tempfile
import yams
@@ -283,9 +288,10 @@
from logilab.common.modutils import get_module_files
from cubicweb.i18n import extract_from_tal, execute
tempdir = tempfile.mkdtemp()
- potfiles = [join(I18NDIR, 'static-messages.pot')]
+ cwi18ndir = WebConfiguration.i18n_lib_dir()
print '-> extract schema messages.'
- schemapot = join(tempdir, 'schema.pot')
+ schemapot = osp.join(tempdir, 'schema.pot')
+ potfiles = [schemapot]
potfiles.append(schemapot)
# explicit close necessary else the file may not be yet flushed when
# we'll using it below
@@ -293,36 +299,43 @@
generate_schema_pot(schemapotstream.write, cubedir=None)
schemapotstream.close()
print '-> extract TAL messages.'
- tali18nfile = join(tempdir, 'tali18n.py')
- extract_from_tal(find(join(BASEDIR, 'web'), ('.py', '.pt')), tali18nfile)
+ tali18nfile = osp.join(tempdir, 'tali18n.py')
+ extract_from_tal(find(osp.join(BASEDIR, 'web'), ('.py', '.pt')),
+ tali18nfile)
print '-> generate .pot files.'
- for id, files, lang in [('pycubicweb', get_module_files(BASEDIR) + list(globfind(join(BASEDIR, 'misc', 'migration'), '*.py')), None),
- ('schemadescr', globfind(join(BASEDIR, 'schemas'), '*.py'), None),
+ pyfiles = get_module_files(BASEDIR)
+ pyfiles += globfind(osp.join(BASEDIR, 'misc', 'migration'), '*.py')
+ schemafiles = globfind(osp.join(BASEDIR, 'schemas'), '*.py')
+ jsfiles = globfind(osp.join(BASEDIR, 'web'), 'cub*.js')
+ for id, files, lang in [('pycubicweb', pyfiles, None),
+ ('schemadescr', schemafiles, None),
('yams', get_module_files(yams.__path__[0]), None),
('tal', [tali18nfile], None),
- ('js', globfind(join(BASEDIR, 'web'), 'cub*.js'), 'java'),
+ ('js', jsfiles, 'java'),
]:
cmd = 'xgettext --no-location --omit-header -k_ -o %s %s'
if lang is not None:
cmd += ' -L %s' % lang
- potfile = join(tempdir, '%s.pot' % id)
+ potfile = osp.join(tempdir, '%s.pot' % id)
execute(cmd % (potfile, ' '.join('"%s"' % f for f in files)))
- if exists(potfile):
+ if osp.exists(potfile):
potfiles.append(potfile)
else:
print '-> WARNING: %s file was not generated' % potfile
print '-> merging %i .pot files' % len(potfiles)
- cubicwebpot = join(tempdir, 'cubicweb.pot')
- execute('msgcat -o %s %s' % (cubicwebpot, ' '.join('"%s"' % f for f in potfiles)))
+ cubicwebpot = osp.join(tempdir, 'cubicweb.pot')
+ execute('msgcat -o %s %s'
+ % (cubicwebpot, ' '.join('"%s"' % f for f in potfiles)))
print '-> merging main pot file with existing translations.'
- chdir(I18NDIR)
+ chdir(cwi18ndir)
toedit = []
- for lang in LANGS:
+ for lang in cw_languages():
target = '%s.po' % lang
- execute('msgmerge -N --sort-output -o "%snew" "%s" "%s"' % (target, target, cubicwebpot))
+ execute('msgmerge -N --sort-output -o "%snew" "%s" "%s"'
+ % (target, target, cubicwebpot))
ensure_fs_mode(target)
shutil.move('%snew' % target, target)
- toedit.append(abspath(target))
+ toedit.append(osp.abspath(target))
# cleanup
rm(tempdir)
# instructions pour la suite
@@ -346,13 +359,14 @@
else:
cubes = [DevConfiguration.cube_dir(cube)
for cube in DevConfiguration.available_cubes()]
- cubes = [cubepath for cubepath in cubes if exists(join(cubepath, 'i18n'))]
+ cubes = [cubepath for cubepath in cubes
+ if osp.exists(osp.join(cubepath, 'i18n'))]
update_cubes_catalogs(cubes)
def update_cubes_catalogs(cubes):
for cubedir in cubes:
- if not isdir(cubedir):
+ if not osp.isdir(cubedir):
print '-> ignoring %s that is not a directory.' % cubedir
continue
try:
@@ -376,20 +390,20 @@
from logilab.common.fileutils import ensure_fs_mode
from logilab.common.shellutils import find, rm
from cubicweb.i18n import extract_from_tal, execute
- cube = basename(normpath(cubedir))
+ cube = osp.basename(osp.normpath(cubedir))
tempdir = tempfile.mkdtemp()
print underline_title('Updating i18n catalogs for cube %s' % cube)
chdir(cubedir)
- if exists(join('i18n', 'entities.pot')):
+ if osp.exists(osp.join('i18n', 'entities.pot')):
warn('entities.pot is deprecated, rename file to static-messages.pot (%s)'
- % join('i18n', 'entities.pot'), DeprecationWarning)
- potfiles = [join('i18n', 'entities.pot')]
- elif exists(join('i18n', 'static-messages.pot')):
- potfiles = [join('i18n', 'static-messages.pot')]
+ % osp.join('i18n', 'entities.pot'), DeprecationWarning)
+ potfiles = [osp.join('i18n', 'entities.pot')]
+ elif osp.exists(osp.join('i18n', 'static-messages.pot')):
+ potfiles = [osp.join('i18n', 'static-messages.pot')]
else:
potfiles = []
print '-> extract schema messages'
- schemapot = join(tempdir, 'schema.pot')
+ schemapot = osp.join(tempdir, 'schema.pot')
potfiles.append(schemapot)
# explicit close necessary else the file may not be yet flushed when
# we'll using it below
@@ -397,30 +411,32 @@
generate_schema_pot(schemapotstream.write, cubedir)
schemapotstream.close()
print '-> extract TAL messages'
- tali18nfile = join(tempdir, 'tali18n.py')
- extract_from_tal(find('.', ('.py', '.pt'), blacklist=STD_BLACKLIST+('test',)), tali18nfile)
+ tali18nfile = osp.join(tempdir, 'tali18n.py')
+ ptfiles = find('.', ('.py', '.pt'), blacklist=STD_BLACKLIST+('test',))
+ extract_from_tal(ptfiles, tali18nfile)
print '-> extract Javascript messages'
- jsfiles = [jsfile for jsfile in find('.', '.js') if basename(jsfile).startswith('cub')]
+ jsfiles = [jsfile for jsfile in find('.', '.js')
+ if osp.basename(jsfile).startswith('cub')]
if jsfiles:
- tmppotfile = join(tempdir, 'js.pot')
- execute('xgettext --no-location --omit-header -k_ -L java --from-code=utf-8 -o %s %s'
- % (tmppotfile, ' '.join(jsfiles)))
+ tmppotfile = osp.join(tempdir, 'js.pot')
+ execute('xgettext --no-location --omit-header -k_ -L java '
+ '--from-code=utf-8 -o %s %s' % (tmppotfile, ' '.join(jsfiles)))
# no pot file created if there are no string to translate
- if exists(tmppotfile):
+ if osp.exists(tmppotfile):
potfiles.append(tmppotfile)
print '-> create cube-specific catalog'
- tmppotfile = join(tempdir, 'generated.pot')
+ tmppotfile = osp.join(tempdir, 'generated.pot')
cubefiles = find('.', '.py', blacklist=STD_BLACKLIST+('test',))
cubefiles.append(tali18nfile)
execute('xgettext --no-location --omit-header -k_ -o %s %s'
% (tmppotfile, ' '.join('"%s"' % f for f in cubefiles)))
- if exists(tmppotfile): # doesn't exists of no translation string found
+ if osp.exists(tmppotfile): # doesn't exists of no translation string found
potfiles.append(tmppotfile)
- potfile = join(tempdir, 'cube.pot')
+ potfile = osp.join(tempdir, 'cube.pot')
print '-> merging %i .pot files:' % len(potfiles)
execute('msgcat -o %s %s' % (potfile,
' '.join('"%s"' % f for f in potfiles)))
- if not exists(potfile):
+ if not osp.exists(potfile):
print 'no message catalog for cube', cube, 'nothing to translate'
# cleanup
rm(tempdir)
@@ -428,16 +444,16 @@
print '-> merging main pot file with existing translations:'
chdir('i18n')
toedit = []
- for lang in LANGS:
+ for lang in cw_languages():
print '-> language', lang
cubepo = '%s.po' % lang
- if not exists(cubepo):
+ if not osp.exists(cubepo):
shutil.copy(potfile, cubepo)
else:
execute('msgmerge -N -s -o %snew %s %s' % (cubepo, cubepo, potfile))
ensure_fs_mode(cubepo)
shutil.move('%snew' % cubepo, cubepo)
- toedit.append(abspath(cubepo))
+ toedit.append(osp.abspath(cubepo))
# cleanup
rm(tempdir)
return toedit
@@ -465,7 +481,7 @@
"""
name = 'newcube'
arguments = '<cubename>'
-
+ min_args = max_args = 1
options = (
("layout",
{'short': 'L', 'type' : 'choice', 'metavar': '<cube layout>',
@@ -546,32 +562,34 @@
def run(self, args):
import re
from logilab.common.shellutils import ASK
- if len(args) != 1:
- raise BadCommandUsage("exactly one argument (cube name) is expected")
cubename = args[0]
if not re.match('[_A-Za-z][_A-Za-z0-9]*$', cubename):
- raise BadCommandUsage("cube name should be a valid python module name")
+ raise BadCommandUsage(
+ 'cube name must be a valid python module name')
verbose = self.get('verbose')
cubesdir = self.get('directory')
if not cubesdir:
cubespath = ServerConfiguration.cubes_search_path()
if len(cubespath) > 1:
- raise BadCommandUsage("can't guess directory where to put the new cube."
- " Please specify it using the --directory option")
+ raise BadCommandUsage(
+ "can't guess directory where to put the new cube."
+ " Please specify it using the --directory option")
cubesdir = cubespath[0]
- if not isdir(cubesdir):
+ if not osp.isdir(cubesdir):
print "-> creating cubes directory", cubesdir
try:
mkdir(cubesdir)
except OSError, err:
- self.fail("failed to create directory %r\n(%s)" % (cubesdir, err))
- cubedir = join(cubesdir, cubename)
- if exists(cubedir):
- self.fail("%s already exists !" % (cubedir))
- skeldir = join(BASEDIR, 'skeleton')
+ self.fail("failed to create directory %r\n(%s)"
+ % (cubesdir, err))
+ cubedir = osp.join(cubesdir, cubename)
+ if osp.exists(cubedir):
+ self.fail("%s already exists !" % cubedir)
+ skeldir = osp.join(BASEDIR, 'skeleton')
default_name = 'cubicweb-%s' % cubename.lower().replace('_', '-')
if verbose:
- distname = raw_input('Debian name for your cube ? [%s]): ' % default_name).strip()
+ distname = raw_input('Debian name for your cube ? [%s]): '
+ % default_name).strip()
if not distname:
distname = default_name
elif not distname.startswith('cubicweb-'):
@@ -580,10 +598,13 @@
else:
distname = default_name
if not re.match('[a-z][-a-z0-9]*$', distname):
- raise BadCommandUsage("cube distname should be a valid debian package name")
- longdesc = shortdesc = raw_input('Enter a short description for your cube: ')
+ raise BadCommandUsage(
+ 'cube distname should be a valid debian package name')
+ longdesc = shortdesc = raw_input(
+ 'Enter a short description for your cube: ')
if verbose:
- longdesc = raw_input('Enter a long description (leave empty to reuse the short one): ')
+ longdesc = raw_input(
+ 'Enter a long description (leave empty to reuse the short one): ')
dependencies = {'cubicweb': '>= %s' % cubicwebversion}
if verbose:
dependencies.update(self._ask_for_dependencies())
@@ -638,8 +659,7 @@
"""
arguments = 'rql.log'
name = 'exlog'
- options = (
- )
+ options = ()
def run(self, args):
import re
@@ -685,34 +705,43 @@
name = "schema"
arguments = '<cube>'
min_args = max_args = 1
- options = [('output-file', {'type':'file', 'default': None,
- 'metavar': '<file>', 'short':'o', 'help':'output image file',
- 'input':False}),
- ('viewer', {'type': 'string', 'default':None,
- 'short': "d", 'metavar':'<cmd>',
- 'help':'command use to view the generated file (empty for none)'}
- ),
- ('show-meta', {'action': 'store_true', 'default':False,
- 'short': "m", 'metavar': "<yN>",
- 'help':'include meta and internal entities in schema'}
- ),
- ('show-workflow', {'action': 'store_true', 'default':False,
- 'short': "w", 'metavar': "<yN>",
- 'help':'include workflow entities in schema'}
- ),
- ('show-cw-user', {'action': 'store_true', 'default':False,
- 'metavar': "<yN>",
- 'help':'include cubicweb user entities in schema'}
- ),
- ('exclude-type', {'type':'string', 'default':'',
- 'short': "x", 'metavar': "<types>",
- 'help':'coma separated list of entity types to remove from view'}
- ),
- ('include-type', {'type':'string', 'default':'',
- 'short': "i", 'metavar': "<types>",
- 'help':'coma separated list of entity types to include in view'}
- ),
- ]
+ options = [
+ ('output-file',
+ {'type':'file', 'default': None,
+ 'metavar': '<file>', 'short':'o', 'help':'output image file',
+ 'input':False,
+ }),
+ ('viewer',
+ {'type': 'string', 'default':None,
+ 'short': "d", 'metavar':'<cmd>',
+ 'help':'command use to view the generated file (empty for none)',
+ }),
+ ('show-meta',
+ {'action': 'store_true', 'default':False,
+ 'short': "m", 'metavar': "<yN>",
+ 'help':'include meta and internal entities in schema',
+ }),
+ ('show-workflow',
+ {'action': 'store_true', 'default':False,
+ 'short': "w", 'metavar': "<yN>",
+ 'help':'include workflow entities in schema',
+ }),
+ ('show-cw-user',
+ {'action': 'store_true', 'default':False,
+ 'metavar': "<yN>",
+ 'help':'include cubicweb user entities in schema',
+ }),
+ ('exclude-type',
+ {'type':'string', 'default':'',
+ 'short': "x", 'metavar': "<types>",
+ 'help':'coma separated list of entity types to remove from view',
+ }),
+ ('include-type',
+ {'type':'string', 'default':'',
+ 'short': "i", 'metavar': "<types>",
+ 'help':'coma separated list of entity types to include in view',
+ }),
+ ]
def run(self, args):
from subprocess import Popen
--- a/devtools/test/unittest_dbfill.py Thu Sep 23 23:28:58 2010 +0200
+++ b/devtools/test/unittest_dbfill.py Wed Sep 29 16:16:32 2010 +0200
@@ -68,7 +68,7 @@
def test_string(self):
"""test string generation"""
surname = self.person_valgen.generate_attribute_value({}, 'surname', 12)
- self.assertEquals(surname, u'é&surname12')
+ self.assertEqual(surname, u'é&surname12')
def test_domain_value(self):
"""test value generation from a given domain value"""
@@ -100,21 +100,21 @@
def test_phone(self):
"""tests make_tel utility"""
- self.assertEquals(make_tel(22030405), '22 03 04 05')
+ self.assertEqual(make_tel(22030405), '22 03 04 05')
def test_customized_generation(self):
- self.assertEquals(self.bug_valgen.generate_attribute_value({}, 'severity', 12),
+ self.assertEqual(self.bug_valgen.generate_attribute_value({}, 'severity', 12),
u'dangerous')
- self.assertEquals(self.bug_valgen.generate_attribute_value({}, 'description', 12),
+ self.assertEqual(self.bug_valgen.generate_attribute_value({}, 'description', 12),
u'yo')
- self.assertEquals(self.person_valgen.generate_attribute_value({}, 'description', 12),
+ self.assertEqual(self.person_valgen.generate_attribute_value({}, 'description', 12),
u'yo')
class ConstraintInsertionTC(TestCase):
def test_writeme(self):
- self.skip('Test automatic insertion / Schema Constraints')
+ self.skipTest('Test automatic insertion / Schema Constraints')
if __name__ == '__main__':
--- a/devtools/test/unittest_httptest.py Thu Sep 23 23:28:58 2010 +0200
+++ b/devtools/test/unittest_httptest.py Wed Sep 29 16:16:32 2010 +0200
@@ -15,7 +15,7 @@
def test_response_anon(self):
response = self.web_get()
- self.assertEquals(response.status, httplib.OK)
+ self.assertEqual(response.status, httplib.OK)
def test_base_url(self):
@@ -29,20 +29,20 @@
def test_response_denied(self):
response = self.web_get()
- self.assertEquals(response.status, httplib.FORBIDDEN)
+ self.assertEqual(response.status, httplib.FORBIDDEN)
def test_login(self):
response = self.web_get()
if response.status != httplib.FORBIDDEN:
- self.skip('Already authenticated')
+ self.skipTest('Already authenticated')
# login
self.web_login(self.admlogin, self.admpassword)
response = self.web_get()
- self.assertEquals(response.status, httplib.OK, response.body)
+ self.assertEqual(response.status, httplib.OK, response.body)
# logout
self.web_logout()
response = self.web_get()
- self.assertEquals(response.status, httplib.FORBIDDEN, response.body)
+ self.assertEqual(response.status, httplib.FORBIDDEN, response.body)
--- a/devtools/test/unittest_qunit.py Thu Sep 23 23:28:58 2010 +0200
+++ b/devtools/test/unittest_qunit.py Wed Sep 29 16:16:32 2010 +0200
@@ -20,7 +20,7 @@
def test_simple_failure(self):
js_tests = list(self._test_qunit(js('test_simple_failure.js')))
- self.assertEquals(len(js_tests), 3)
+ self.assertEqual(len(js_tests), 3)
test_1, test_2, test_3 = js_tests
self.assertRaises(self.failureException, test_1[0], *test_1[1:])
self.assertRaises(self.failureException, test_2[0], *test_2[1:])
--- a/devtools/test/unittest_testlib.py Thu Sep 23 23:28:58 2010 +0200
+++ b/devtools/test/unittest_testlib.py Wed Sep 29 16:16:32 2010 +0200
@@ -20,9 +20,8 @@
"""
from cStringIO import StringIO
-from unittest import TestSuite
-from logilab.common.testlib import (TestCase, unittest_main,
+from logilab.common.testlib import (TestCase, unittest_main, TestSuite,
SkipAwareTextTestRunner)
from cubicweb.devtools import htmlparser
@@ -47,9 +46,9 @@
tests = [MyWebTest('test_error_view'), MyWebTest('test_correct_view')]
result = self.runner.run(TestSuite(tests))
- self.assertEquals(result.testsRun, 2)
- self.assertEquals(len(result.errors), 0)
- self.assertEquals(len(result.failures), 1)
+ self.assertEqual(result.testsRun, 2)
+ self.assertEqual(len(result.errors), 0)
+ self.assertEqual(len(result.failures), 1)
clean_repo_test_cls(MyWebTest)
@@ -104,7 +103,7 @@
def test_source1(self):
"""make sure source is stored correctly"""
- self.assertEquals(self.page_info.source, HTML_PAGE2)
+ self.assertEqual(self.page_info.source, HTML_PAGE2)
def test_source2(self):
"""make sure source is stored correctly - raise exception"""
@@ -114,47 +113,47 @@
def test_has_title_no_level(self):
"""tests h? tags information"""
- self.assertEquals(self.page_info.has_title('Test'), True)
- self.assertEquals(self.page_info.has_title('Test '), False)
- self.assertEquals(self.page_info.has_title('Tes'), False)
- self.assertEquals(self.page_info.has_title('Hello world !'), True)
+ self.assertEqual(self.page_info.has_title('Test'), True)
+ self.assertEqual(self.page_info.has_title('Test '), False)
+ self.assertEqual(self.page_info.has_title('Tes'), False)
+ self.assertEqual(self.page_info.has_title('Hello world !'), True)
def test_has_title_level(self):
"""tests h? tags information"""
- self.assertEquals(self.page_info.has_title('Test', level = 1), True)
- self.assertEquals(self.page_info.has_title('Test', level = 2), False)
- self.assertEquals(self.page_info.has_title('Test', level = 3), False)
- self.assertEquals(self.page_info.has_title('Test', level = 4), False)
+ self.assertEqual(self.page_info.has_title('Test', level = 1), True)
+ self.assertEqual(self.page_info.has_title('Test', level = 2), False)
+ self.assertEqual(self.page_info.has_title('Test', level = 3), False)
+ self.assertEqual(self.page_info.has_title('Test', level = 4), False)
self.assertRaises(IndexError, self.page_info.has_title, 'Test', level = 5)
def test_has_title_regexp_no_level(self):
"""tests has_title_regexp() with no particular level specified"""
- self.assertEquals(self.page_info.has_title_regexp('h[23] title'), True)
+ self.assertEqual(self.page_info.has_title_regexp('h[23] title'), True)
def test_has_title_regexp_level(self):
"""tests has_title_regexp() with a particular level specified"""
- self.assertEquals(self.page_info.has_title_regexp('h[23] title', 2), True)
- self.assertEquals(self.page_info.has_title_regexp('h[23] title', 3), True)
- self.assertEquals(self.page_info.has_title_regexp('h[23] title', 4), False)
+ self.assertEqual(self.page_info.has_title_regexp('h[23] title', 2), True)
+ self.assertEqual(self.page_info.has_title_regexp('h[23] title', 3), True)
+ self.assertEqual(self.page_info.has_title_regexp('h[23] title', 4), False)
def test_appears(self):
"""tests PageInfo.appears()"""
- self.assertEquals(self.page_info.appears('CW'), True)
- self.assertEquals(self.page_info.appears('Logilab'), True)
- self.assertEquals(self.page_info.appears('Logilab introduces'), True)
- self.assertEquals(self.page_info.appears('H2 title'), False)
+ self.assertEqual(self.page_info.appears('CW'), True)
+ self.assertEqual(self.page_info.appears('Logilab'), True)
+ self.assertEqual(self.page_info.appears('Logilab introduces'), True)
+ self.assertEqual(self.page_info.appears('H2 title'), False)
def test_has_link(self):
"""tests has_link()"""
- self.assertEquals(self.page_info.has_link('Logilab'), True)
- self.assertEquals(self.page_info.has_link('logilab'), False)
- self.assertEquals(self.page_info.has_link('Logilab', 'http://www.logilab.org'), True)
- self.assertEquals(self.page_info.has_link('Logilab', 'http://www.google.com'), False)
+ self.assertEqual(self.page_info.has_link('Logilab'), True)
+ self.assertEqual(self.page_info.has_link('logilab'), False)
+ self.assertEqual(self.page_info.has_link('Logilab', 'http://www.logilab.org'), True)
+ self.assertEqual(self.page_info.has_link('Logilab', 'http://www.google.com'), False)
def test_has_link_regexp(self):
"""test has_link_regexp()"""
- self.assertEquals(self.page_info.has_link_regexp('L[oi]gilab'), True)
- self.assertEquals(self.page_info.has_link_regexp('L[ai]gilab'), False)
+ self.assertEqual(self.page_info.has_link_regexp('L[oi]gilab'), True)
+ self.assertEqual(self.page_info.has_link_regexp('L[ai]gilab'), False)
if __name__ == '__main__':
--- a/devtools/testlib.py Thu Sep 23 23:28:58 2010 +0200
+++ b/devtools/testlib.py Wed Sep 29 16:16:32 2010 +0200
@@ -347,15 +347,19 @@
"""return a connection for the given login/password"""
if login == self.admlogin:
self.restore_connection()
- else:
- if not kwargs:
- kwargs['password'] = str(login)
- self.cnx = repo_connect(self.repo, unicode(login), **kwargs)
- self.websession = DBAPISession(self.cnx)
- self._cnxs.append(self.cnx)
+ # definitly don't want autoclose when used as a context manager
+ return self.cnx
+ autoclose = kwargs.pop('autoclose', True)
+ if not kwargs:
+ kwargs['password'] = str(login)
+ self.cnx = repo_connect(self.repo, unicode(login), **kwargs)
+ self.websession = DBAPISession(self.cnx)
+ self._cnxs.append(self.cnx)
if login == self.vreg.config.anonymous_user()[0]:
self.cnx.anonymous_connection = True
- return TestCaseConnectionProxy(self, self.cnx)
+ if autoclose:
+ return TestCaseConnectionProxy(self, self.cnx)
+ return self.cnx
def restore_connection(self):
if not self.cnx is self._orig_cnx[0]:
--- a/doc/book/en/annexes/faq.rst Thu Sep 23 23:28:58 2010 +0200
+++ b/doc/book/en/annexes/faq.rst Wed Sep 29 16:16:32 2010 +0200
@@ -402,6 +402,17 @@
mydb=> update cw_cwuser set cw_upassword='qHO8282QN5Utg' where cw_login='joe';
UPDATE 1
+if you're running over SQL Server, you need to use the CONVERT
+function to convert the string to varbinary(255). The SQL query is
+therefore::
+
+ update cw_cwuser set cw_upassword=CONVERT(varbinary(255), 'qHO8282QN5Utg') where cw_login='joe';
+
+Be careful, the encryption algorithm is different on Windows and on
+Unix. You cannot therefore use a hash generated on Unix to fill in a
+Windows database, nor the other way round.
+
+
You can prefer use a migration script similar to this shell invocation instead::
$ cubicweb-ctl shell <instance>
--- a/doc/book/en/devrepo/datamodel/definition.rst Thu Sep 23 23:28:58 2010 +0200
+++ b/doc/book/en/devrepo/datamodel/definition.rst Wed Sep 29 16:16:32 2010 +0200
@@ -82,10 +82,16 @@
a set of attributes and relations, and some permissions which define who can add, read,
update or delete entities of this type.
-The following built-in types are available: ``String``, ``Int``,
-``Float``, ``Decimal``, ``Boolean``, ``Date``, ``Datetime``, ``Time``,
-``Interval``, ``Byte`` and ``Password``. They can only be used as
-attributes of an other entity type.
+The following built-in types are available: ``String``,
+``Int``, ``Float``, ``Decimal``, ``Boolean``,
+``Date``, ``Datetime``, ``Time``, ``Interval``, ``Byte`` and
+``Password``. They can only be used as attributes of an other entity
+type.
+
+There is also a `RichString` kindof type:
+
+ .. autoclass:: yams.buildobjs.RichString
+
You can find more base entity types in
:ref:`pre_defined_entity_types`.
@@ -518,6 +524,8 @@
birth and a relation that connects a `Person` to another entity of type
`Company` through the semantic `works_for`.
+
+
:Naming convention:
Entity class names must start with an uppercase letter. The common
--- a/doc/book/en/devrepo/devcore/dbapi.rst Thu Sep 23 23:28:58 2010 +0200
+++ b/doc/book/en/devrepo/devcore/dbapi.rst Wed Sep 29 16:16:32 2010 +0200
@@ -22,9 +22,12 @@
.. note::
- While executing update queries (SET, INSERT, DELETE), if a query generates
- an error related to security, a rollback is automatically done on the current
- transaction.
+ If a query generates an error related to security (:exc:`Unauthorized`) or to
+ integrity (:exc:`ValidationError`), a rollback is automatically done on the
+ current transaction.
+
+ Also, a rollback is done if an error occurs during commit.
+
Executing RQL queries from a view or a hook
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- a/doc/book/en/devrepo/repo/hooks.rst Thu Sep 23 23:28:58 2010 +0200
+++ b/doc/book/en/devrepo/repo/hooks.rst Wed Sep 29 16:16:32 2010 +0200
@@ -6,6 +6,7 @@
.. autodocstring:: cubicweb.server.hook
+
Example using dataflow hooks
----------------------------
@@ -30,8 +31,8 @@
class PersonAgeRange(Hook):
__regid__ = 'person_age_range'
+ __select__ = Hook.__select__ & is_instance('Person')
events = ('before_add_entity', 'before_update_entity')
- __select__ = Hook.__select__ & is_instance('Person')
def __call__(self):
if 'age' in self.entity.cw_edited:
@@ -96,6 +97,8 @@
.. sourcecode:: python
+ from cubicweb.server.hook import Hook, Operation, match_rtype
+
def check_cycle(self, session, eid, rtype, role='subject'):
parents = set([eid])
parent = session.entity_from_eid(eid)
@@ -146,15 +149,15 @@
class CheckSubsidiaryCycleOp(Operation):
def precommit_event(self):
- for eid in self._cw.transaction_data.pop('subsidiary_cycle_detection'):
- check_cycle(self.session, eid, 'subsidiary_of')
+ for eid in self.session.transaction_data['subsidiary_cycle_detection']:
+ check_cycle(self.session, eid, self.rtype)
Here, we call :func:`set_operation` so that we will simply accumulate eids of
-entities to check at the end in a single CheckSubsidiaryCycleOp operation. Value
-are stored in a set associated to the 'subsidiary_cycle_detection' transaction
-data key. The set initialization and operation creation are handled nicely by
-:func:set_operation.
+entities to check at the end in a single `CheckSubsidiaryCycleOp`
+operation. Value are stored in a set associated to the
+'subsidiary_cycle_detection' transaction data key. The set initialization and
+operation creation are handled nicely by :func:`set_operation`.
A more realistic example can be found in the advanced tutorial chapter
:ref:`adv_tuto_security_propagation`.
--- a/doc/book/en/devrepo/testing.rst Thu Sep 23 23:28:58 2010 +0200
+++ b/doc/book/en/devrepo/testing.rst Wed Sep 29 16:16:32 2010 +0200
@@ -42,6 +42,8 @@
`sync_schema_props_perms()` fonction of the migration environment
need not a database regeneration step.
+.. _hook_test:
+
Unit test by example
````````````````````
@@ -85,6 +87,14 @@
The test case itself checks that an Operation does it job of
preventing cycles amongst Keyword entities.
+`create_entity` is a useful method, which easily allows to create an
+entity. You can link this entity to others entities, by specifying as
+argument, the relation name, and the entity to link, as value. In the
+above example, the `Classification` entity is linked to a `CWEtype`
+via the relation `classifies`. Conversely, if you are creating a
+`CWEtype` entity, you can link it to a `Classification` entity, by
+adding `reverse_classifies` as argument.
+
.. note::
:meth:`commit` method is not called automatically in test_XXX
--- a/doc/book/en/devweb/controllers.rst Thu Sep 23 23:28:58 2010 +0200
+++ b/doc/book/en/devweb/controllers.rst Wed Sep 29 16:16:32 2010 +0200
@@ -15,13 +15,12 @@
`Browsing`:
-* the View controlleris associated with most browsing actions within a
- CubicWeb application: it always instantiates a
- :ref:`the_main_template` and lets the ResultSet/Views dispatch
- system build up the whole content; it handles ObjectNotFound and
- NoSelectableObject errors that may bubble up to its entry point, in
- an end-user-friendly way (but other programming errors will slip
- through)
+* the View controller is associated with most browsing actions within a
+ CubicWeb application: it always instantiates a :ref:`the_main_template` and
+ lets the ResultSet/Views dispatch system build up the whole content; it
+ handles :exc:`ObjectNotFound` and :exc:`NoSelectableObject` errors that may
+ bubble up to its entry point, in an end-user-friendly way (but other
+ programming errors will slip through)
* the JSon controller (same module) provides services for Ajax calls,
typically using JSON as a serialization format for input, and
@@ -49,7 +48,7 @@
for outgoing email notifications
* the MailBugReport controller (web/views/basecontrollers.py) allows
- to quickly have a `repotbug` feature in one's application
+ to quickly have a `reportbug` feature in one's application
Registration
++++++++++++
--- a/doc/book/en/devweb/views/table.rst Thu Sep 23 23:28:58 2010 +0200
+++ b/doc/book/en/devweb/views/table.rst Wed Sep 29 16:16:32 2010 +0200
@@ -7,6 +7,10 @@
Creates a HTML table (`<table>`) and call the view `cell` for each cell of
the result set. Applicable on any result set.
+*editable-table*
+ Creates an **editable** HTML table (`<table>`) and call the view `cell` for each cell of
+ the result set. Applicable on any result set.
+
*cell*
By default redirects to the `final` view if this is a final entity or
`outofcontext` view otherwise
@@ -17,3 +21,58 @@
.. autoclass:: cubicweb.web.views.tableview.TableView
:members:
+
+Example
+```````
+
+Let us take an example from the timesheet cube:
+
+.. sourcecode:: python
+
+ class ActivityTable(EntityView):
+ __regid__ = 'activitytable'
+ __select__ = is_instance('Activity')
+ title = _('activitytable')
+
+ def call(self, showresource=True):
+ _ = self._cw._
+ headers = [_("diem"), _("duration"), _("workpackage"), _("description"), _("state"), u""]
+ eids = ','.join(str(row[0]) for row in self.cw_rset)
+ rql = ('Any R, D, DUR, WO, DESCR, S, A, SN, RT, WT ORDERBY D DESC '
+ 'WHERE '
+ ' A is Activity, A done_by R, R title RT, '
+ ' A diem D, A duration DUR, '
+ ' A done_for WO, WO title WT, '
+ ' A description DESCR, A in_state S, S name SN, A eid IN (%s)' % eids)
+ if showresource:
+ displaycols = range(7)
+ headers.insert(0, display_name(self._cw, 'Resource'))
+ else: # skip resource column if asked to
+ displaycols = range(1, 7)
+ rset = self._cw.execute(rql)
+ self.wview('editable-table', rset, 'null',
+ displayfilter=True, displayactions=False,
+ headers=headers, displaycols=displaycols,
+ cellvids={3: 'editable-final'})
+
+To obtain an editable table, specify 'edtitable-table' as vid. You
+have to select the entity in the rql request too (in order to kwnow
+which entity must be edited). You can specify an optional
+`displaycols` argument which defines column's indexes that will be
+displayed. In the above example, setting `showresource` to `False`
+will only render columns from index 1 to 7.
+
+The previous example results in:
+
+.. image:: ../../images/views-table-shadow.png
+
+
+In order to activate table filter mechanism, set the `displayfilter`
+argument to True. A small arrow will be displayed at the table's top
+right corner. Clicking on `show filter form` action, will display the
+filter form as below:
+
+.. image:: ../../images/views-table-filter-shadow.png
+
+By the same way, you can display all registered actions for the
+selected entity, setting `displayactions` argument to True.
Binary file doc/book/en/images/views-table-filter-shadow.png has changed
Binary file doc/book/en/images/views-table-filter.png has changed
Binary file doc/book/en/images/views-table-shadow.png has changed
Binary file doc/book/en/images/views-table.png has changed
--- a/entities/test/unittest_base.py Thu Sep 23 23:28:58 2010 +0200
+++ b/entities/test/unittest_base.py Wed Sep 29 16:16:32 2010 +0200
@@ -44,16 +44,16 @@
self.login(u'member')
entity = self.request().create_entity('Bookmark', title=u"hello", path=u'project/cubicweb')
self.commit()
- self.assertEquals(entity.creator.eid, self.member.eid)
- self.assertEquals(entity.dc_creator(), u'member')
+ self.assertEqual(entity.creator.eid, self.member.eid)
+ self.assertEqual(entity.dc_creator(), u'member')
def test_type(self):
- self.assertEquals(self.member.dc_type(), 'cwuser')
+ self.assertEqual(self.member.dc_type(), 'cwuser')
def test_entity_meta_attributes(self):
# XXX move to yams
- self.assertEquals(self.schema['CWUser'].meta_attributes(), {})
- self.assertEquals(dict((str(k), v) for k, v in self.schema['State'].meta_attributes().iteritems()),
+ self.assertEqual(self.schema['CWUser'].meta_attributes(), {})
+ self.assertEqual(dict((str(k), v) for k, v in self.schema['State'].meta_attributes().iteritems()),
{'description_format': ('format', 'description')})
@@ -63,20 +63,20 @@
email2 = self.execute('INSERT EmailAddress X: X address "maarten@philips.com"').get_entity(0, 0)
email3 = self.execute('INSERT EmailAddress X: X address "toto@logilab.fr"').get_entity(0, 0)
email1.set_relations(prefered_form=email2)
- self.assertEquals(email1.prefered.eid, email2.eid)
- self.assertEquals(email2.prefered.eid, email2.eid)
- self.assertEquals(email3.prefered.eid, email3.eid)
+ self.assertEqual(email1.prefered.eid, email2.eid)
+ self.assertEqual(email2.prefered.eid, email2.eid)
+ self.assertEqual(email3.prefered.eid, email3.eid)
def test_mangling(self):
email = self.execute('INSERT EmailAddress X: X address "maarten.ter.huurne@philips.com"').get_entity(0, 0)
- self.assertEquals(email.display_address(), 'maarten.ter.huurne@philips.com')
- self.assertEquals(email.printable_value('address'), 'maarten.ter.huurne@philips.com')
+ self.assertEqual(email.display_address(), 'maarten.ter.huurne@philips.com')
+ self.assertEqual(email.printable_value('address'), 'maarten.ter.huurne@philips.com')
self.vreg.config.global_set_option('mangle-emails', True)
- self.assertEquals(email.display_address(), 'maarten.ter.huurne at philips dot com')
- self.assertEquals(email.printable_value('address'), 'maarten.ter.huurne at philips dot com')
+ self.assertEqual(email.display_address(), 'maarten.ter.huurne at philips dot com')
+ self.assertEqual(email.printable_value('address'), 'maarten.ter.huurne at philips dot com')
email = self.execute('INSERT EmailAddress X: X address "syt"').get_entity(0, 0)
- self.assertEquals(email.display_address(), 'syt')
- self.assertEquals(email.printable_value('address'), 'syt')
+ self.assertEqual(email.display_address(), 'syt')
+ self.assertEqual(email.printable_value('address'), 'syt')
class CWUserTC(BaseEntityTC):
@@ -94,19 +94,19 @@
def test_dc_title_and_name(self):
e = self.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
- self.assertEquals(e.dc_title(), 'member')
- self.assertEquals(e.name(), 'member')
+ self.assertEqual(e.dc_title(), 'member')
+ self.assertEqual(e.name(), 'member')
e.set_attributes(firstname=u'bouah')
- self.assertEquals(e.dc_title(), 'member')
- self.assertEquals(e.name(), u'bouah')
+ self.assertEqual(e.dc_title(), 'member')
+ self.assertEqual(e.name(), u'bouah')
e.set_attributes(surname=u'lôt')
- self.assertEquals(e.dc_title(), 'member')
- self.assertEquals(e.name(), u'bouah lôt')
+ self.assertEqual(e.dc_title(), 'member')
+ self.assertEqual(e.name(), u'bouah lôt')
def test_allowed_massmail_keys(self):
e = self.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
# Bytes/Password attributes should be omited
- self.assertEquals(e.cw_adapt_to('IEmailable').allowed_massmail_keys(),
+ self.assertEqual(e.cw_adapt_to('IEmailable').allowed_massmail_keys(),
set(('surname', 'firstname', 'login', 'last_login_time',
'creation_date', 'modification_date', 'cwuri', 'eid'))
)
@@ -144,7 +144,7 @@
# no specific class for Subdivisions, the default one should be selected
eclass = self.select_eclass('SubDivision')
self.failUnless(eclass.__autogenerated__)
- #self.assertEquals(eclass.__bases__, (AnyEntity,))
+ #self.assertEqual(eclass.__bases__, (AnyEntity,))
# build class from most generic to most specific and make
# sure the most specific is always selected
self.vreg._loadedmods[__name__] = {}
@@ -156,12 +156,12 @@
self.failUnless(eclass.__autogenerated__)
self.failIf(eclass is Foo)
if etype == 'SubDivision':
- self.assertEquals(eclass.__bases__, (Foo,))
+ self.assertEqual(eclass.__bases__, (Foo,))
else:
- self.assertEquals(eclass.__bases__[0].__bases__, (Foo,))
+ self.assertEqual(eclass.__bases__[0].__bases__, (Foo,))
# check Division eclass is still selected for plain Division entities
eclass = self.select_eclass('Division')
- self.assertEquals(eclass.__regid__, 'Division')
+ self.assertEqual(eclass.__regid__, 'Division')
if __name__ == '__main__':
unittest_main()
--- a/entities/test/unittest_wfobjs.py Thu Sep 23 23:28:58 2010 +0200
+++ b/entities/test/unittest_wfobjs.py Wed Sep 29 16:16:32 2010 +0200
@@ -43,12 +43,12 @@
wf = add_wf(self, 'Company')
foo = wf.add_state(u'foo', initial=True)
bar = wf.add_state(u'bar')
- self.assertEquals(wf.state_by_name('bar').eid, bar.eid)
- self.assertEquals(wf.state_by_name('barrr'), None)
+ self.assertEqual(wf.state_by_name('bar').eid, bar.eid)
+ self.assertEqual(wf.state_by_name('barrr'), None)
baz = wf.add_transition(u'baz', (foo,), bar, ('managers',))
- self.assertEquals(wf.transition_by_name('baz').eid, baz.eid)
- self.assertEquals(len(baz.require_group), 1)
- self.assertEquals(baz.require_group[0].name, 'managers')
+ self.assertEqual(wf.transition_by_name('baz').eid, baz.eid)
+ self.assertEqual(len(baz.require_group), 1)
+ self.assertEqual(baz.require_group[0].name, 'managers')
def test_duplicated_state(self):
wf = add_wf(self, 'Company')
@@ -56,7 +56,7 @@
self.commit()
wf.add_state(u'foo')
ex = self.assertRaises(ValidationError, self.commit)
- self.assertEquals(ex.errors, {'name-subject': 'workflow already have a state of that name'})
+ self.assertEqual(ex.errors, {'name-subject': 'workflow already have a state of that name'})
# no pb if not in the same workflow
wf2 = add_wf(self, 'Company')
foo = wf2.add_state(u'foo', initial=True)
@@ -66,7 +66,7 @@
self.commit()
bar.set_attributes(name=u'foo')
ex = self.assertRaises(ValidationError, self.commit)
- self.assertEquals(ex.errors, {'name-subject': 'workflow already have a state of that name'})
+ self.assertEqual(ex.errors, {'name-subject': 'workflow already have a state of that name'})
def test_duplicated_transition(self):
wf = add_wf(self, 'Company')
@@ -75,7 +75,7 @@
wf.add_transition(u'baz', (foo,), bar, ('managers',))
wf.add_transition(u'baz', (bar,), foo)
ex = self.assertRaises(ValidationError, self.commit)
- self.assertEquals(ex.errors, {'name-subject': 'workflow already have a transition of that name'})
+ self.assertEqual(ex.errors, {'name-subject': 'workflow already have a transition of that name'})
# no pb if not in the same workflow
wf2 = add_wf(self, 'Company')
foo = wf.add_state(u'foo', initial=True)
@@ -87,7 +87,7 @@
self.commit()
biz.set_attributes(name=u'baz')
ex = self.assertRaises(ValidationError, self.commit)
- self.assertEquals(ex.errors, {'name-subject': 'workflow already have a transition of that name'})
+ self.assertEqual(ex.errors, {'name-subject': 'workflow already have a transition of that name'})
class WorkflowTC(CubicWebTC):
@@ -95,13 +95,13 @@
def setup_database(self):
rschema = self.schema['in_state']
for rdef in rschema.rdefs.values():
- self.assertEquals(rdef.cardinality, '1*')
+ self.assertEqual(rdef.cardinality, '1*')
self.member = self.create_user('member')
def test_workflow_base(self):
e = self.create_user('toto')
iworkflowable = e.cw_adapt_to('IWorkflowable')
- self.assertEquals(iworkflowable.state, 'activated')
+ self.assertEqual(iworkflowable.state, 'activated')
iworkflowable.change_state('deactivated', u'deactivate 1')
self.commit()
iworkflowable.change_state('activated', u'activate 1')
@@ -109,33 +109,33 @@
iworkflowable.change_state('deactivated', u'deactivate 2')
self.commit()
e.cw_clear_relation_cache('wf_info_for', 'object')
- self.assertEquals([tr.comment for tr in e.reverse_wf_info_for],
+ self.assertEqual([tr.comment for tr in e.reverse_wf_info_for],
['deactivate 1', 'activate 1', 'deactivate 2'])
- self.assertEquals(iworkflowable.latest_trinfo().comment, 'deactivate 2')
+ self.assertEqual(iworkflowable.latest_trinfo().comment, 'deactivate 2')
def test_possible_transitions(self):
user = self.execute('CWUser X').get_entity(0, 0)
iworkflowable = user.cw_adapt_to('IWorkflowable')
trs = list(iworkflowable.possible_transitions())
- self.assertEquals(len(trs), 1)
- self.assertEquals(trs[0].name, u'deactivate')
- self.assertEquals(trs[0].destination(None).name, u'deactivated')
+ self.assertEqual(len(trs), 1)
+ self.assertEqual(trs[0].name, u'deactivate')
+ self.assertEqual(trs[0].destination(None).name, u'deactivated')
# test a std user get no possible transition
cnx = self.login('member')
# fetch the entity using the new session
trs = list(cnx.user().cw_adapt_to('IWorkflowable').possible_transitions())
- self.assertEquals(len(trs), 0)
+ self.assertEqual(len(trs), 0)
def _test_manager_deactivate(self, user):
iworkflowable = user.cw_adapt_to('IWorkflowable')
user.cw_clear_relation_cache('in_state', 'subject')
- self.assertEquals(len(user.in_state), 1)
- self.assertEquals(iworkflowable.state, 'deactivated')
+ self.assertEqual(len(user.in_state), 1)
+ self.assertEqual(iworkflowable.state, 'deactivated')
trinfo = iworkflowable.latest_trinfo()
- self.assertEquals(trinfo.previous_state.name, 'activated')
- self.assertEquals(trinfo.new_state.name, 'deactivated')
- self.assertEquals(trinfo.comment, 'deactivate user')
- self.assertEquals(trinfo.comment_format, 'text/plain')
+ self.assertEqual(trinfo.previous_state.name, 'activated')
+ self.assertEqual(trinfo.new_state.name, 'deactivated')
+ self.assertEqual(trinfo.comment, 'deactivate user')
+ self.assertEqual(trinfo.comment_format, 'text/plain')
return trinfo
def test_change_state(self):
@@ -143,7 +143,7 @@
iworkflowable = user.cw_adapt_to('IWorkflowable')
iworkflowable.change_state('deactivated', comment=u'deactivate user')
trinfo = self._test_manager_deactivate(user)
- self.assertEquals(trinfo.transition, None)
+ self.assertEqual(trinfo.transition, None)
def test_set_in_state_bad_wf(self):
wf = add_wf(self, 'CWUser')
@@ -153,7 +153,7 @@
ex = self.assertRaises(ValidationError, self.session.execute,
'SET X in_state S WHERE X eid %(x)s, S eid %(s)s',
{'x': self.user().eid, 's': s.eid})
- self.assertEquals(ex.errors, {'in_state-subject': "state doesn't belong to entity's workflow. "
+ self.assertEqual(ex.errors, {'in_state-subject': "state doesn't belong to entity's workflow. "
"You may want to set a custom workflow for this entity first."})
def test_fire_transition(self):
@@ -161,10 +161,10 @@
iworkflowable = user.cw_adapt_to('IWorkflowable')
iworkflowable.fire_transition('deactivate', comment=u'deactivate user')
user.clear_all_caches()
- self.assertEquals(iworkflowable.state, 'deactivated')
+ self.assertEqual(iworkflowable.state, 'deactivated')
self._test_manager_deactivate(user)
trinfo = self._test_manager_deactivate(user)
- self.assertEquals(trinfo.transition.name, 'deactivate')
+ self.assertEqual(trinfo.transition.name, 'deactivate')
def test_goback_transition(self):
wf = self.session.user.cw_adapt_to('IWorkflowable').current_workflow
@@ -179,7 +179,7 @@
self.commit()
iworkflowable.fire_transition('wake up')
self.commit()
- self.assertEquals(iworkflowable.state, 'activated')
+ self.assertEqual(iworkflowable.state, 'activated')
iworkflowable.fire_transition('deactivate')
self.commit()
iworkflowable.fire_transition('rest')
@@ -187,7 +187,7 @@
iworkflowable.fire_transition('wake up')
self.commit()
user.clear_all_caches()
- self.assertEquals(iworkflowable.state, 'deactivated')
+ self.assertEqual(iworkflowable.state, 'deactivated')
# XXX test managers can change state without matching transition
@@ -199,7 +199,7 @@
iworkflowable = req.entity_from_eid(self.member.eid).cw_adapt_to('IWorkflowable')
ex = self.assertRaises(ValidationError,
iworkflowable.fire_transition, 'deactivate')
- self.assertEquals(ex.errors, {'by_transition-subject': "transition may not be fired"})
+ self.assertEqual(ex.errors, {'by_transition-subject': "transition may not be fired"})
cnx.close()
cnx = self.login('member')
req = self.request()
@@ -208,7 +208,7 @@
cnx.commit()
ex = self.assertRaises(ValidationError,
iworkflowable.fire_transition, 'activate')
- self.assertEquals(ex.errors, {'by_transition-subject': "transition may not be fired"})
+ self.assertEqual(ex.errors, {'by_transition-subject': "transition may not be fired"})
def test_fire_transition_owned_by(self):
self.execute('INSERT RQLExpression X: X exprtype "ERQLExpression", '
@@ -255,34 +255,34 @@
state3 = mwf.add_state(u'state3')
swftr1 = mwf.add_wftransition(u'swftr1', swf, state1,
[(swfstate2, state2), (swfstate3, state3)])
- self.assertEquals(swftr1.destination(None).eid, swfstate1.eid)
+ self.assertEqual(swftr1.destination(None).eid, swfstate1.eid)
# workflows built, begin test
group = self.request().create_entity('CWGroup', name=u'grp1')
self.commit()
iworkflowable = group.cw_adapt_to('IWorkflowable')
- self.assertEquals(iworkflowable.current_state.eid, state1.eid)
- self.assertEquals(iworkflowable.current_workflow.eid, mwf.eid)
- self.assertEquals(iworkflowable.main_workflow.eid, mwf.eid)
- self.assertEquals(iworkflowable.subworkflow_input_transition(), None)
+ self.assertEqual(iworkflowable.current_state.eid, state1.eid)
+ self.assertEqual(iworkflowable.current_workflow.eid, mwf.eid)
+ self.assertEqual(iworkflowable.main_workflow.eid, mwf.eid)
+ self.assertEqual(iworkflowable.subworkflow_input_transition(), None)
iworkflowable.fire_transition('swftr1', u'go')
self.commit()
group.clear_all_caches()
- self.assertEquals(iworkflowable.current_state.eid, swfstate1.eid)
- self.assertEquals(iworkflowable.current_workflow.eid, swf.eid)
- self.assertEquals(iworkflowable.main_workflow.eid, mwf.eid)
- self.assertEquals(iworkflowable.subworkflow_input_transition().eid, swftr1.eid)
+ self.assertEqual(iworkflowable.current_state.eid, swfstate1.eid)
+ self.assertEqual(iworkflowable.current_workflow.eid, swf.eid)
+ self.assertEqual(iworkflowable.main_workflow.eid, mwf.eid)
+ self.assertEqual(iworkflowable.subworkflow_input_transition().eid, swftr1.eid)
iworkflowable.fire_transition('tr1', u'go')
self.commit()
group.clear_all_caches()
- self.assertEquals(iworkflowable.current_state.eid, state2.eid)
- self.assertEquals(iworkflowable.current_workflow.eid, mwf.eid)
- self.assertEquals(iworkflowable.main_workflow.eid, mwf.eid)
- self.assertEquals(iworkflowable.subworkflow_input_transition(), None)
+ self.assertEqual(iworkflowable.current_state.eid, state2.eid)
+ self.assertEqual(iworkflowable.current_workflow.eid, mwf.eid)
+ self.assertEqual(iworkflowable.main_workflow.eid, mwf.eid)
+ self.assertEqual(iworkflowable.subworkflow_input_transition(), None)
# force back to swfstate1 is impossible since we can't any more find
# subworkflow input transition
ex = self.assertRaises(ValidationError,
iworkflowable.change_state, swfstate1, u'gadget')
- self.assertEquals(ex.errors, {'to_state-subject': "state doesn't belong to entity's workflow"})
+ self.assertEqual(ex.errors, {'to_state-subject': "state doesn't belong to entity's workflow"})
self.rollback()
# force back to state1
iworkflowable.change_state('state1', u'gadget')
@@ -291,10 +291,10 @@
iworkflowable.fire_transition('tr2', u'chapeau')
self.commit()
group.clear_all_caches()
- self.assertEquals(iworkflowable.current_state.eid, state3.eid)
- self.assertEquals(iworkflowable.current_workflow.eid, mwf.eid)
- self.assertEquals(iworkflowable.main_workflow.eid, mwf.eid)
- self.assertListEquals(parse_hist(iworkflowable.workflow_history),
+ self.assertEqual(iworkflowable.current_state.eid, state3.eid)
+ self.assertEqual(iworkflowable.current_workflow.eid, mwf.eid)
+ self.assertEqual(iworkflowable.main_workflow.eid, mwf.eid)
+ self.assertListEqual(parse_hist(iworkflowable.workflow_history),
[('state1', 'swfstate1', 'swftr1', 'go'),
('swfstate1', 'swfstate2', 'tr1', 'go'),
('swfstate2', 'state2', 'swftr1', 'exiting from subworkflow subworkflow'),
@@ -318,7 +318,7 @@
mwf.add_wftransition(u'swftr1', swf, state1,
[(swfstate2, state2), (swfstate2, state3)])
ex = self.assertRaises(ValidationError, self.commit)
- self.assertEquals(ex.errors, {'subworkflow_exit-subject': u"can't have multiple exits on the same state"})
+ self.assertEqual(ex.errors, {'subworkflow_exit-subject': u"can't have multiple exits on the same state"})
def test_swf_fire_in_a_row(self):
# sub-workflow
@@ -382,7 +382,7 @@
iworkflowable.fire_transition(trans)
self.commit()
group.clear_all_caches()
- self.assertEquals(iworkflowable.state, nextstate)
+ self.assertEqual(iworkflowable.state, nextstate)
class CustomWorkflowTC(CubicWebTC):
@@ -400,12 +400,12 @@
{'wf': wf.eid, 'x': self.member.eid})
self.member.clear_all_caches()
iworkflowable = self.member.cw_adapt_to('IWorkflowable')
- self.assertEquals(iworkflowable.state, 'activated')# no change before commit
+ self.assertEqual(iworkflowable.state, 'activated')# no change before commit
self.commit()
self.member.clear_all_caches()
- self.assertEquals(iworkflowable.current_workflow.eid, wf.eid)
- self.assertEquals(iworkflowable.state, 'asleep')
- self.assertEquals(iworkflowable.workflow_history, ())
+ self.assertEqual(iworkflowable.current_workflow.eid, wf.eid)
+ self.assertEqual(iworkflowable.state, 'asleep')
+ self.assertEqual(iworkflowable.workflow_history, ())
def test_custom_wf_replace_state_keep_history(self):
"""member in inital state with some history, state is redirected and
@@ -420,9 +420,9 @@
{'wf': wf.eid, 'x': self.member.eid})
self.commit()
self.member.clear_all_caches()
- self.assertEquals(iworkflowable.current_workflow.eid, wf.eid)
- self.assertEquals(iworkflowable.state, 'asleep')
- self.assertEquals(parse_hist(iworkflowable.workflow_history),
+ self.assertEqual(iworkflowable.current_workflow.eid, wf.eid)
+ self.assertEqual(iworkflowable.state, 'asleep')
+ self.assertEqual(parse_hist(iworkflowable.workflow_history),
[('activated', 'deactivated', 'deactivate', None),
('deactivated', 'activated', 'activate', None),
('activated', 'asleep', None, 'workflow changed to "CWUser"')])
@@ -436,7 +436,7 @@
self.execute('SET X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
{'wf': wf.eid, 'x': self.member.eid})
ex = self.assertRaises(ValidationError, self.commit)
- self.assertEquals(ex.errors, {'custom_workflow-subject': u'workflow has no initial state'})
+ self.assertEqual(ex.errors, {'custom_workflow-subject': u'workflow has no initial state'})
def test_custom_wf_bad_etype(self):
"""try to set a custom workflow which doesn't apply to entity type"""
@@ -445,7 +445,7 @@
self.execute('SET X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
{'wf': wf.eid, 'x': self.member.eid})
ex = self.assertRaises(ValidationError, self.commit)
- self.assertEquals(ex.errors, {'custom_workflow-subject': u"workflow isn't a workflow for this type"})
+ self.assertEqual(ex.errors, {'custom_workflow-subject': u"workflow isn't a workflow for this type"})
def test_del_custom_wf(self):
"""member in some state shared by the new workflow, nothing has to be
@@ -461,12 +461,12 @@
self.execute('DELETE X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
{'wf': wf.eid, 'x': self.member.eid})
self.member.clear_all_caches()
- self.assertEquals(iworkflowable.state, 'asleep')# no change before commit
+ self.assertEqual(iworkflowable.state, 'asleep')# no change before commit
self.commit()
self.member.clear_all_caches()
- self.assertEquals(iworkflowable.current_workflow.name, "default user workflow")
- self.assertEquals(iworkflowable.state, 'activated')
- self.assertEquals(parse_hist(iworkflowable.workflow_history),
+ self.assertEqual(iworkflowable.current_workflow.name, "default user workflow")
+ self.assertEqual(iworkflowable.state, 'activated')
+ self.assertEqual(parse_hist(iworkflowable.workflow_history),
[('activated', 'deactivated', 'deactivate', None),
('deactivated', 'asleep', None, 'workflow changed to "CWUser"'),
('asleep', 'activated', None, 'workflow changed to "default user workflow"'),])
@@ -492,24 +492,24 @@
{'wf': wf.eid, 'x': user.eid})
self.commit()
user.clear_all_caches()
- self.assertEquals(iworkflowable.state, 'asleep')
- self.assertEquals([t.name for t in iworkflowable.possible_transitions()],
+ self.assertEqual(iworkflowable.state, 'asleep')
+ self.assertEqual([t.name for t in iworkflowable.possible_transitions()],
['rest'])
iworkflowable.fire_transition('rest')
self.commit()
user.clear_all_caches()
- self.assertEquals(iworkflowable.state, 'asleep')
- self.assertEquals([t.name for t in iworkflowable.possible_transitions()],
+ self.assertEqual(iworkflowable.state, 'asleep')
+ self.assertEqual([t.name for t in iworkflowable.possible_transitions()],
['rest'])
- self.assertEquals(parse_hist(iworkflowable.workflow_history),
+ self.assertEqual(parse_hist(iworkflowable.workflow_history),
[('asleep', 'asleep', 'rest', None)])
user.set_attributes(surname=u'toto') # fulfill condition
self.commit()
iworkflowable.fire_transition('rest')
self.commit()
user.clear_all_caches()
- self.assertEquals(iworkflowable.state, 'dead')
- self.assertEquals(parse_hist(iworkflowable.workflow_history),
+ self.assertEqual(iworkflowable.state, 'dead')
+ self.assertEqual(parse_hist(iworkflowable.workflow_history),
[('asleep', 'asleep', 'rest', None),
('asleep', 'asleep', 'rest', None),
('asleep', 'dead', 'sick', None),])
@@ -521,7 +521,7 @@
{'wf': wf.eid, 'x': user.eid})
self.commit()
iworkflowable = user.cw_adapt_to('IWorkflowable')
- self.assertEquals(iworkflowable.state, 'dead')
+ self.assertEqual(iworkflowable.state, 'dead')
def test_auto_transition_initial_state_fired(self):
wf = self.execute('Any WF WHERE ET default_workflow WF, '
@@ -534,7 +534,7 @@
user = self.create_user('member', surname=u'toto')
self.commit()
iworkflowable = user.cw_adapt_to('IWorkflowable')
- self.assertEquals(iworkflowable.state, 'dead')
+ self.assertEqual(iworkflowable.state, 'dead')
class WorkflowHooksTC(CubicWebTC):
@@ -555,7 +555,7 @@
self.commit()
initialstate = self.execute('Any N WHERE S name N, X in_state S, X eid %(x)s',
{'x' : ueid})[0][0]
- self.assertEquals(initialstate, u'activated')
+ self.assertEqual(initialstate, u'activated')
# give access to users group on the user's wf transitions
# so we can test wf enforcing on euser (managers don't have anymore this
# enforcement
@@ -592,7 +592,7 @@
iworkflowable = user.cw_adapt_to('IWorkflowable')
ex = self.assertRaises(ValidationError,
iworkflowable.fire_transition, 'activate')
- self.assertEquals(self._cleanup_msg(ex.errors['by_transition-subject']),
+ self.assertEqual(self._cleanup_msg(ex.errors['by_transition-subject']),
u"transition isn't allowed from")
cnx.close()
@@ -602,7 +602,7 @@
iworkflowable = user.cw_adapt_to('IWorkflowable')
ex = self.assertRaises(ValidationError,
iworkflowable.fire_transition, 'dummy')
- self.assertEquals(self._cleanup_msg(ex.errors['by_transition-subject']),
+ self.assertEqual(self._cleanup_msg(ex.errors['by_transition-subject']),
u"transition isn't allowed from")
cnx.close()
@@ -616,7 +616,7 @@
session.set_pool()
ex = self.assertRaises(ValidationError,
iworkflowable.fire_transition, 'deactivate')
- self.assertEquals(self._cleanup_msg(ex.errors['by_transition-subject']),
+ self.assertEqual(self._cleanup_msg(ex.errors['by_transition-subject']),
u"transition isn't allowed from")
# get back now
iworkflowable.fire_transition('activate')
--- a/ext/test/unittest_rest.py Thu Sep 23 23:28:58 2010 +0200
+++ b/ext/test/unittest_rest.py Wed Sep 29 16:16:32 2010 +0200
@@ -29,9 +29,9 @@
def test_eid_role(self):
context = self.context()
- self.assertEquals(rest_publish(context, ':eid:`%s`' % context.eid),
+ self.assertEqual(rest_publish(context, ':eid:`%s`' % context.eid),
'<p><a class="reference" href="http://testing.fr/cubicweb/cwuser/admin">#%s</a></p>\n' % context.eid)
- self.assertEquals(rest_publish(context, ':eid:`%s:some text`' % context.eid),
+ self.assertEqual(rest_publish(context, ':eid:`%s:some text`' % context.eid),
'<p><a class="reference" href="http://testing.fr/cubicweb/cwuser/admin">some text</a></p>\n')
def test_bad_rest_no_crash(self):
--- a/goa/__init__.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""cubicweb on google appengine
-
-"""
-__docformat__ = "restructuredtext en"
-
-
-try:
- # WARNING: do not import the google's db module here since it will take
- # precedence over our own db submodule
- from google.appengine.api.datastore import Key, Get, Query
- from google.appengine.api.datastore_errors import BadKeyError
-except ImportError:
- # not in google app environment
- pass
-else:
-
- import os
- _SS = os.environ.get('SERVER_SOFTWARE')
- if _SS is None:
- MODE = 'test'
- elif _SS.startswith('Dev'):
- MODE = 'dev'
- else:
- MODE = 'prod'
-
- from cubicweb.server import SOURCE_TYPES
- from cubicweb.goa.gaesource import GAESource
- SOURCE_TYPES['gae'] = GAESource
-
-
- def do_monkey_patch():
-
- # monkey patch yams Bytes validator since it should take a bytes string with gae
- # and not a StringIO
- def check_bytes(eschema, value):
- """check value is a bytes string"""
- return isinstance(value, str)
- from yams import constraints
- constraints.BASE_CHECKERS['Bytes'] = check_bytes
-
- def rql_for_eid(eid):
- return 'Any X WHERE X eid "%s"' % eid
- from cubicweb import uilib
- uilib.rql_for_eid = rql_for_eid
-
- def typed_eid(eid):
- try:
- return str(Key(eid))
- except BadKeyError:
- raise ValueError(eid)
- import cubicweb
- cubicweb.typed_eid = typed_eid
-
- # XXX monkey patch cubicweb.schema.CubicWebSchema to have string eid with
- # optional cardinality (since eid is set after the validation)
-
- import re
- from yams import buildobjs as ybo
-
- def add_entity_type(self, edef):
- edef.name = edef.name.encode()
- assert re.match(r'[A-Z][A-Za-z0-9]*[a-z]+[0-9]*$', edef.name), repr(edef.name)
- eschema = super(CubicWebSchema, self).add_entity_type(edef)
- if not eschema.final:
- # automatically add the eid relation to non final entity types
- rdef = ybo.RelationDefinition(eschema.type, 'eid', 'Bytes',
- cardinality='?1', uid=True)
- self.add_relation_def(rdef)
- rdef = ybo.RelationDefinition(eschema.type, 'identity', eschema.type)
- self.add_relation_def(rdef)
- self._eid_index[eschema.eid] = eschema
- return eschema
-
- from cubicweb.schema import CubicWebSchema
- CubicWebSchema.add_entity_type = add_entity_type
-
-
- # don't reset vreg on repository set_schema
- from cubicweb.server import repository
- orig_set_schema = repository.Repository.set_schema
- def set_schema(self, schema, resetvreg=True):
- orig_set_schema(self, schema, False)
- repository.Repository.set_schema = set_schema
- # deactivate function ensuring relation cardinality consistency
- repository.del_existing_rel_if_needed = lambda *args: None
-
- def get_cubes(self):
- """return the list of top level cubes used by this instance"""
- config = self.config
- cubes = config['included-cubes'] + config['included-yams-cubes']
- return config.expand_cubes(cubes)
- repository.Repository.get_cubes = get_cubes
-
- from rql import RQLHelper
- RQLHelper.simplify = lambda x, r: None
-
- # activate entity caching on the server side
-
- def set_entity_cache(self, entity):
- self.transaction_data.setdefault('_eid_cache', {})[entity.eid] = entity
-
- def entity_cache(self, eid):
- return self.transaction_data['_eid_cache'][eid]
-
- def drop_entity_cache(self, eid=None):
- if eid is None:
- self.transaction_data['_eid_cache'] = {}
- elif '_eid_cache' in self.transaction_data:
- self.transaction_data['_eid_cache'].pop(eid, None)
-
- def datastore_get(self, key):
- if isinstance(key, basestring):
- key = Key(key)
- try:
- gentity = self.transaction_data['_key_cache'][key]
- #self.critical('cached %s', gentity)
- except KeyError:
- gentity = Get(key)
- #self.critical('Get %s', gentity)
- self.transaction_data.setdefault('_key_cache', {})[key] = gentity
- return gentity
-
- def clear_datastore_cache(self, key=None):
- if key is None:
- self.transaction_data['_key_cache'] = {}
- else:
- if isinstance(key, basestring):
- key = Key(key)
- self.transaction_data['_key_cache'].pop(key, None)
-
- from cubicweb.server.session import Session
- Session.set_entity_cache = set_entity_cache
- Session.entity_cache = entity_cache
- Session.drop_entity_cache = drop_entity_cache
- Session.datastore_get = datastore_get
- Session.clear_datastore_cache = clear_datastore_cache
-
- from docutils.frontend import OptionParser
- # avoid a call to expanduser which is not available under gae
- def get_standard_config_files(self):
- return self.standard_config_files
- OptionParser.get_standard_config_files = get_standard_config_files
--- a/goa/appobjects/__init__.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
--- a/goa/appobjects/components.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""overrides some base views for cubicweb on google appengine"""
-
-__docformat__ = "restructuredtext en"
-
-from logilab.mtconverter import xml_escape
-
-from cubicweb import typed_eid
-from cubicweb.selectors import one_line_rset, match_search_state, accept
-from cubicweb.schema import display_name
-from cubicweb.view import StartupView, EntityView
-from cubicweb.web import Redirect
-from cubicweb.web.views import vid_from_rset
-
-from google.appengine.api import mail
-
-
-class SearchForAssociationView(EntityView):
- """view called by the edition view when the user asks
- to search for something to link to the edited eid
- """
- id = 'search-associate'
-
- __select__ = one_line_rset() & match_search_state('linksearch') & accept
-
- def cell_call(self, row, col):
- entity = self.rset.get_entity(0, 0)
- role, eid, rtype, etype = self.req.search_state[1]
- assert entity.eid == typed_eid(eid)
- rset = entity.unrelated(rtype, etype, role, ordermethod='fetch_order')
- vid = vid_from_rset(self.req, rset, self.schema)
- self.w(u'<div id="search-associate-content">')
- self.pagination(self.req, rset, w=self.w)
- self.wview(vid, rset)
- self.w(u'</div>')
-
-
-class SchemaImageView(StartupView):
- id = 'schemagraph'
- binary = True
- content_type = 'image/png'
- def call(self):
- """display global schema information"""
- skipmeta = int(self.req.form.get('skipmeta', 1))
- if skipmeta:
- url = self.build_url('data/schema.png')
- else:
- url = self.build_url('data/metaschema.png')
- raise Redirect(url)
-
-
-from cubicweb.web.views.baseviews import MetaDataView
-
-class GAEMetaDataView(MetaDataView):
- show_eid = False
-
-
-from cubicweb.web.views.startup import ManageView
-
-def entity_types_no_count(self, eschemas):
- """return a list of formatted links to get a list of entities of
- a each entity's types
- """
- req = self.req
- for eschema in eschemas:
- if eschema.final or not (eschema.has_perm(req, 'read') or
- eschema.has_local_role('read')):
- continue
- etype = eschema.type
- label = display_name(req, etype, 'plural')
- view = self.vreg.select('views', 'list', req, req.etype_rset(etype))
- url = view.url()
- etypelink = u' <a href="%s">%s</a>' % (xml_escape(url), label)
- if eschema.has_perm(req, 'add'):
- yield (label, etypelink, self.add_entity_link(etype))
-
-ManageView.entity_types = entity_types_no_count
-
-
-from cubicweb.web.views.basecontrollers import SendMailController
-
-def sendmail(self, recipient, subject, body):
- sender = '%s <%s>' % (
- self.req.user.dc_title() or self.config['sender-name'],
- self.req.user.cw_adapt_to('IEmailable').get_email() or self.config['sender-addr'])
- mail.send_mail(sender=sender, to=recipient,
- subject=subject, body=body)
-
-SendMailController.sendmail = sendmail
--- a/goa/appobjects/dbmgmt.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""special management views to manage repository content (initialization and
-restoration).
-
-"""
-__docformat__ = "restructuredtext en"
-
-from os.path import exists, join, abspath
-from pickle import loads, dumps
-
-from logilab.common.decorators import cached
-from logilab.mtconverter import xml_escape
-
-from cubicweb.selectors import none_rset, match_user_groups
-from cubicweb.view import StartupView
-from cubicweb.web import Redirect
-from cubicweb.goa.dbinit import fix_entities, init_persistent_schema, insert_versions
-
-from google.appengine.api.datastore import Entity, Key, Get, Put, Delete
-from google.appengine.api.datastore_types import Blob
-from google.appengine.api.datastore_errors import EntityNotFoundError
-
-
-def _get_status(name, create=True):
- key = Key.from_path('EApplicationStatus', name)
- try:
- status = Get(key)
- except EntityNotFoundError:
- if create:
- status = Entity('EApplicationStatus', name=name)
- else:
- status = None
- return status
-
-
-class AuthInfo(StartupView):
- """special management view to get cookie values to give to laxctl commands
- which are doing datastore administration requests
- """
- id = 'authinfo'
- __select__ = none_rset() & match_user_groups('managers')
-
- def call(self):
- cookie = self.req.get_cookie()
- values = []
- if self.config['use-google-auth']:
- for param in ('ACSID', 'dev_appserver_login'):
- morsel = cookie.get(param)
- if morsel:
- values.append('%s=%s' % (param, morsel.value))
- break
- values.append('__session=%s' % cookie['__session'].value)
- self.w(u"<p>pass this flag to the client: --cookie='%s'</p>"
- % xml_escape('; '.join(values)))
-
-
-
-class ContentInit(StartupView):
- """special management view to initialize content of a repository,
- step by step to avoid depassing quotas
- """
- id = 'contentinit'
- __select__ = none_rset() & match_user_groups('managers')
-
- def server_session(self):
- ssession = self.config.repo_session(self.req.cnx.sessionid)
- ssession.set_pool()
- return ssession
-
- def end_core_step(self, msg, status, stepid):
- status['cpath'] = ''
- status['stepid'] = stepid
- Put(status)
- self.msg(msg)
-
- def call(self):
- status = _get_status('creation')
- if status.get('finished'):
- self.redirect('process already completed')
- config = self.config
- # execute cubicweb's post<event> script
- #mhandler.exec_event_script('post%s' % event)
- # execute cubes'post<event> script if any
- paths = [p for p in config.cubes_path() + [config.apphome]
- if exists(join(p, 'migration'))]
- paths = [abspath(p) for p in (reversed(paths))]
- cpath = status.get('cpath')
- if cpath is None and status.get('stepid') is None:
- init_persistent_schema(self.server_session(), self.schema)
- self.end_core_step(u'inserted schema entities', status, 0)
- return
- if cpath == '' and status.get('stepid') == 0:
- fix_entities(self.schema)
- self.end_core_step(u'fixed bootstrap groups and users', status, 1)
- return
- if cpath == '' and status.get('stepid') == 1:
- insert_versions(self.server_session(), self.config)
- self.end_core_step(u'inserted software versions', status, None)
- return
- for i, path in enumerate(paths):
- if not cpath or cpath == path:
- self.info('running %s', path)
- stepid = status.get('stepid')
- context = status.get('context')
- if context is not None:
- context = loads(context)
- else:
- context = {}
- stepid = self._migrhandler.exec_event_script(
- 'postcreate', path, 'stepable_postcreate', stepid, context)
- if stepid is None: # finished for this script
- # reset script state
- context = stepid = None
- # next time, go to the next script
- self.msg(u'finished postcreate for %s' % path)
- try:
- path = paths[i+1]
- self.continue_link()
- except IndexError:
- status['finished'] = True
- path = None
- self.redirect('process completed')
- else:
- if context.get('stepidx'):
- self.msg(u'created %s entities for step %s of %s' % (
- context['stepidx'], stepid, path))
- else:
- self.msg(u'finished postcreate step %s for %s' % (
- stepid, path))
- context = Blob(dumps(context))
- self.continue_link()
- status['context'] = context
- status['stepid'] = stepid
- status['cpath'] = path
- break
- else:
- if not cpath:
- # nothing to be done
- status['finished'] = True
- self.redirect('process completed')
- else:
- # Note the error: is expected by the laxctl command line tool,
- # deal with this if internationalization is introduced
- self.msg(u'error: strange creation state, can\'t find %s'
- % cpath)
- self.w(u'<div>click <a href="%s?vid=contentclear">here</a> to '
- '<b>delete all datastore content</b> so process can be '
- 'reinitialized</div>' % xml_escape(self.req.base_url()))
- Put(status)
-
- @property
- @cached
- def _migrhandler(self):
- return self.config.migration_handler(self.schema, interactive=False,
- cnx=self.req.cnx,
- repo=self.config.repository())
-
- def msg(self, msg):
- self.w(u'<div class="message">%s</div>' % xml_escape(msg))
- def redirect(self, msg):
- raise Redirect(self.req.build_url('', msg))
- def continue_link(self):
- self.w(u'<a href="%s">continue</a><br/>' % xml_escape(self.req.url()))
-
-
-class ContentClear(StartupView):
- id = 'contentclear'
- __select__ = none_rset() & match_user_groups('managers')
- skip_etypes = ('CWGroup', 'CWUser')
-
- def call(self):
- # XXX should use unsafe execute with all hooks deactivated
- # XXX step by catching datastore errors?
- for eschema in self.schema.entities():
- if eschema.final or eschema in self.skip_etypes:
- continue
- self.req.execute('DELETE %s X' % eschema)
- self.w(u'deleted all %s entities<br/>' % eschema)
- status = _get_status('creation', create=False)
- if status:
- Delete(status)
- self.w(u'done<br/>')
- self.w(u'click <a href="%s?vid=contentinit">here</a> to start the data '
- 'initialization process<br/>' % self.req.base_url())
--- a/goa/appobjects/gauthservice.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""authentication using google authentication service
-
-"""
-__docformat__ = "restructuredtext en"
-
-from cubicweb.web.views.basecomponents import UserLink
-from cubicweb.web.views.actions import LogoutAction
-
-from google.appengine.api import users
-
-
-class GACWUserLink(UserLink):
-
- def anon_user_link(self):
- self.w(self.req._('anonymous'))
- self.w(u' [<a class="logout" href="%s">%s</a>]'
- % (users.create_login_url(self.req.url()), self.req._('login')))
-
-class GAELogoutAction(LogoutAction):
-
- def url(self):
- return users.create_logout_url(self.req.build_url('logout') )
-
-def registration_callback(vreg):
- if hasattr(vreg.config, 'has_resource'):
- vreg.register(GACWUserLink, clear=True)
- vreg.register(GAELogoutAction, clear=True)
--- a/goa/appobjects/sessions.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,291 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""persistent sessions stored in big table
-
-
-XXX TODO:
-* cleanup persistent session
-* use user as ancestor?
-"""
-__docformat__ = "restructuredtext en"
-
-from pickle import loads, dumps
-from time import localtime, strftime
-
-from logilab.common.decorators import cached, clear_cache
-
-from cubicweb import BadConnectionId
-from cubicweb.dbapi import Connection, ConnectionProperties, repo_connect
-from cubicweb.selectors import none_rset, match_user_groups
-from cubicweb.server.session import Session
-from cubicweb.web import InvalidSession
-from cubicweb.web.application import AbstractSessionManager
-from cubicweb.web.application import AbstractAuthenticationManager
-
-from google.appengine.api.datastore import Key, Entity, Get, Put, Delete, Query
-from google.appengine.api.datastore_errors import EntityNotFoundError
-from google.appengine.api.datastore_types import Blob
-
-try:
- del Connection.__del__
-except AttributeError:
- pass # already deleted
-
-
-class GAEAuthenticationManager(AbstractAuthenticationManager):
- """authenticate user associated to a request and check session validity,
- using google authentication service
- """
-
- def __init__(self, *args, **kwargs):
- super(GAEAuthenticationManager, self).__init__(*args, **kwargs)
- self._repo = self.config.repository(vreg=self.vreg)
-
- def authenticate(self, req, _login=None, _password=None):
- """authenticate user and return an established connection for this user
-
- :raise ExplicitLogin: if authentication is required (no authentication
- info found or wrong user/password)
- """
- if _login is not None:
- login, password = _login, _password
- else:
- login, password = req.get_authorization()
- # remove possibly cached cursor coming from closed connection
- clear_cache(req, 'cursor')
- cnxprops = ConnectionProperties(self.vreg.config.repo_method,
- close=False, log=False)
- cnx = repo_connect(self._repo, login, password=password, cnxprops=cnxprops)
- self._init_cnx(cnx, login, password)
- # associate the connection to the current request
- req.set_connection(cnx)
- return cnx
-
- def _init_cnx(self, cnx, login, password):
- cnx.anonymous_connection = self.config.is_anonymous_user(login)
- cnx.vreg = self.vreg
- cnx.login = login
- cnx.password = password
-
-
-class GAEPersistentSessionManager(AbstractSessionManager):
- """manage session data associated to a session identifier"""
-
- def __init__(self, vreg, *args, **kwargs):
- super(GAEPersistentSessionManager, self).__init__(vreg, *args, **kwargs)
- self._repo = self.config.repository(vreg=vreg)
-
- def get_session(self, req, sessionid):
- """return existing session for the given session identifier"""
- # search a record for the given session
- key = Key.from_path('CubicWebSession', 'key_' + sessionid, parent=None)
- try:
- record = Get(key)
- except EntityNotFoundError:
- raise InvalidSession()
- repo = self._repo
- if self.has_expired(record):
- repo._sessions.pop(sessionid, None)
- Delete(record)
- raise InvalidSession()
- # associate it with a repository session
- try:
- reposession = repo._get_session(sessionid)
- user = reposession.user
- # touch session to avoid closing our own session when sessions are
- # cleaned (touch is done on commit/rollback on the server side, too
- # late in that case)
- reposession._touch()
- except BadConnectionId:
- # can't found session in the repository, this probably mean the
- # session is not yet initialized on this server, hijack the repo
- # to create it
- # use an internal connection
- ssession = repo.internal_session()
- # try to get a user object
- try:
- user = repo.authenticate_user(ssession, record['login'],
- record['password'])
- finally:
- ssession.close()
- reposession = Session(user, self._repo, _id=sessionid)
- self._repo._sessions[sessionid] = reposession
- cnx = Connection(self._repo, sessionid)
- return self._get_proxy(req, record, cnx, user)
-
- def open_session(self, req):
- """open and return a new session for the given request"""
- cnx = self.authmanager.authenticate(req)
- # avoid rebuilding a user
- user = self._repo._get_session(cnx.sessionid).user
- # build persistent record for session data
- record = Entity('CubicWebSession', name='key_' + cnx.sessionid)
- record['login'] = cnx.login
- record['password'] = cnx.password
- record['anonymous_connection'] = cnx.anonymous_connection
- Put(record)
- return self._get_proxy(req, record, cnx, user)
-
- def close_session(self, proxy):
- """close session on logout or on invalid session detected (expired out,
- corrupted...)
- """
- proxy.close()
-
- def current_sessions(self):
- for record in Query('CubicWebSession').Run():
- yield ConnectionProxy(record)
-
- def _get_proxy(self, req, record, cnx, user):
- proxy = ConnectionProxy(record, cnx, user)
- user.req = req
- req.set_connection(proxy, user)
- return proxy
-
-
-class ConnectionProxy(object):
-
- def __init__(self, record, cnx=None, user=None):
- self.__record = record
- self.__cnx = cnx
- self.__user = user
- self.__data = None
- self.__is_dirty = False
- self.sessionid = record.key().name()[4:] # remove 'key_' prefix
-
- def __repr__(self):
- sstr = '<ConnectionProxy %s' % self.sessionid
- if self.anonymous_connection:
- sstr += ' (anonymous)'
- elif self.__user:
- sstr += ' for %s' % self.__user.login
- sstr += ', last used %s>' % strftime('%T', localtime(self.last_usage_time))
- return sstr
-
- def __getattribute__(self, name):
- try:
- return super(ConnectionProxy, self).__getattribute__(name)
- except AttributeError:
- return getattr(self.__cnx, name)
-
- def _set_last_usage_time(self, value):
- self.__is_dirty = True
- self.__record['last_usage_time'] = value
- def _get_last_usage_time(self):
- return self.__record['last_usage_time']
-
- last_usage_time = property(_get_last_usage_time, _set_last_usage_time)
-
- @property
- def anonymous_connection(self):
- # use get() for bw compat if sessions without anonymous information are
- # found. Set default to True to limit lifetime of those sessions.
- return self.__record.get('anonymous_connection', True)
-
- @property
- @cached
- def data(self):
- if self.__record.get('data') is not None:
- try:
- return loads(self.__record['data'])
- except:
- self.__is_dirty = True
- self.exception('corrupted session data for session %s',
- self.__cnx)
- return {}
-
- def get_session_data(self, key, default=None, pop=False):
- """return value associated to `key` in session data"""
- if pop:
- try:
- value = self.data.pop(key)
- self.__is_dirty = True
- return value
- except KeyError:
- return default
- else:
- return self.data.get(key, default)
-
- def set_session_data(self, key, value):
- """set value associated to `key` in session data"""
- self.data[key] = value
- self.__is_dirty = True
-
- def del_session_data(self, key):
- """remove value associated to `key` in session data"""
- try:
- del self.data[key]
- self.__is_dirty = True
- except KeyError:
- pass
-
- def commit(self):
- if self.__is_dirty:
- self.__save()
- self.__cnx.commit()
-
- def rollback(self):
- self.__save()
- self.__cnx.rollback()
-
- def close(self):
- if self.__cnx is not None:
- self.__cnx.close()
- Delete(self.__record)
-
- def __save(self):
- if self.__is_dirty:
- self.__record['data'] = Blob(dumps(self.data))
- Put(self.__record)
- self.__is_dirty = False
-
- def user(self, req=None, props=None):
- """return the User object associated to this connection"""
- return self.__user
-
-
-import logging
-from cubicweb import set_log_methods
-set_log_methods(ConnectionProxy, logging.getLogger('cubicweb.web.goa.session'))
-
-
-from cubicweb.view import StartupView
-from cubicweb.web import application
-
-class SessionsCleaner(StartupView):
- id = 'cleansessions'
- __select__ = none_rset() & match_user_groups('managers')
-
- def call(self):
- # clean web session
- session_manager = application.SESSION_MANAGER
- nbclosed, remaining = session_manager.clean_sessions()
- self.w(u'<div class="message">')
- self.w(u'%s web sessions closed<br/>\n' % nbclosed)
- # clean repository sessions
- repo = self.config.repository(vreg=self.vreg)
- nbclosed = repo.clean_sessions()
- self.w(u'%s repository sessions closed<br/>\n' % nbclosed)
- self.w(u'%s remaining sessions<br/>\n' % remaining)
- self.w(u'</div>')
-
-
-def registration_callback(vreg):
- vreg.register(SessionsCleaner)
- vreg.register(GAEAuthenticationManager, clear=True)
- vreg.register(GAEPersistentSessionManager, clear=True)
--- a/goa/bin/laxctl Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-import os.path as osp
-
-APPLROOT = osp.abspath(osp.join(osp.dirname(osp.abspath(__file__)), '..'))
-if APPLROOT not in sys.path:
- sys.path.insert(0, APPLROOT)
-CUBES_DIR = osp.join(APPLROOT, 'cw-cubes')
-if CUBES_DIR not in sys.path:
- sys.path.insert(1, CUBES_DIR)
-
-try:
- import custom
-except ImportError, exc:
- print exc
- sys.exit(2)
-
-from tools.laxctl import run
-run()
--- a/goa/db.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,469 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""provide replacement classes for gae db module, so that a gae model can be
-used as base for a cubicweb application by simply replacing ::
-
- from google.appengine.ext import db
-
-by
-
- from cubicweb.goa import db
-
-The db.model api should be fully featured by replacement classes, with the
-following differences:
-
-* all methods returning `google.appengine.ext.db.Model` instance(s) will return
- `cubicweb.goa.db.Model` instance instead (though you should see almost no
- difference since those instances have the same api)
-
-* class methods returning model instance take a `req` as first argument, unless
- they are called through an instance, representing the current request
- (accessible through `self.req` on almost all objects)
-
-* XXX no instance.<modelname>_set attributes, use instance.reverse_<attr name>
- instead
-* XXX reference property always return a list of objects, not the instance
-* XXX name/collection_name argument of properties constructor are ignored
-* XXX ListProperty
-
-"""
-__docformat__ = "restructuredtext en"
-
-from copy import deepcopy
-
-from logilab.common.decorators import cached, iclassmethod
-
-from cubicweb import Binary, entities
-from cubicweb.req import RequestSessionBase
-from cubicweb.rset import ResultSet
-from cubicweb.entity import metaentity
-from cubicweb.server.utils import crypt_password
-from cubicweb.goa import MODE
-from cubicweb.goa.dbinit import init_relations
-
-from google.appengine.api.datastore import Get, Put, Key, Entity, Query
-from google.appengine.api.datastore import NormalizeAndTypeCheck, RunInTransaction
-from google.appengine.api.datastore_types import Text, Blob
-from google.appengine.api.datastore_errors import BadKeyError
-
-# XXX remove this dependancy
-from google.appengine.ext import db
-
-
-def rset_from_objs(req, objs, attrs=('eid',), rql=None, args=None):
- """return a ResultSet instance for list of objects"""
- if objs is None:
- objs = ()
- elif isinstance(objs, Entity):
- objs = (objs,)
- if rql is None:
- rql = 'Any X'
- rows = []
- description = []
- rset = ResultSet(rows, rql, args, description=description)
- vreg = req.vreg
- for i, obj in enumerate(objs):
- line = []
- linedescr = []
- eschema = vreg.schema.eschema(obj.kind())
- for j, attr in enumerate(attrs):
- if attr == 'eid':
- value = obj.key()
- obj.row, obj.col = i, j
- descr = eschema.type
- value = str(value)
- else:
- value = obj[attr]
- descr = str(eschema.destination(attr))
- line.append(value)
- linedescr.append(descr)
- rows.append(line)
- description.append(linedescr)
- for j, attr in enumerate(attrs):
- if attr == 'eid':
- entity = vreg.etype_class(eschema.type)(req, rset, i, j)
- rset._get_entity_cache_ = {(i, j): entity}
- rset.rowcount = len(rows)
- rset.req = req
- return rset
-
-
-def needrequest(wrapped):
- def wrapper(cls, *args, **kwargs):
- req = kwargs.pop('req', None)
- if req is None and args and isinstance(args[0], RequestSessionBase):
- args = list(args)
- req = args.pop(0)
- if req is None:
- req = getattr(cls, 'req', None)
- if req is None:
- raise Exception('either call this method on an instance or '
- 'specify the req argument')
- return wrapped(cls, req, *args, **kwargs)
- return iclassmethod(wrapper)
-
-
-class gaedbmetaentity(metaentity):
- """metaclass for goa.db.Model classes: filter entity / db model part,
- put aside the db model part for later creation of db model class.
- """
- def __new__(mcs, name, bases, classdict):
- if not 'id' in classdict:
- classdict['id'] = name
- entitycls = super(gaedbmetaentity, mcs).__new__(mcs, name, bases, classdict)
- return entitycls
-
-
-TEST_MODELS = {}
-
-def extract_dbmodel(entitycls):
- if MODE == 'test' and entitycls in TEST_MODELS:
- dbclassdict = TEST_MODELS[entitycls]
- else:
- dbclassdict = {}
- for attr, value in entitycls.__dict__.items():
- if isinstance(value, db.Property) or isinstance(value, ReferencePropertyStub):
- dbclassdict[attr] = value
- # don't remove attr from entitycls, this make tests fail, and it's anyway
- # overwritten by descriptor at class initialization time
- #delattr(entitycls, attr)
- if MODE == 'test':
- TEST_MODELS[entitycls] = dbclassdict
- dbclassdict = deepcopy(dbclassdict)
- for propname, prop in TEST_MODELS[entitycls].iteritems():
- if getattr(prop, 'reference_class', None) is db._SELF_REFERENCE:
- dbclassdict[propname].reference_class = db._SELF_REFERENCE
- return dbclassdict
-
-
-class Model(entities.AnyEntity):
- id = 'Any'
- __metaclass__ = gaedbmetaentity
-
- row = col = 0
-
- @classmethod
- def __initialize__(cls):
- super(Model, cls).__initialize__()
- cls._attributes = frozenset(rschema for rschema in cls.e_schema.subject_relations()
- if rschema.final)
-
- def __init__(self, *args, **kwargs):
- # db.Model prototype:
- # __init__(self, parent=None, key_name=None, **kw)
- #
- # Entity prototype:
- # __init__(self, req, rset, row=None, col=0)
- if args and isinstance(args[0], RequestSessionBase) or 'req' in kwargs:
- super(Model, self).__init__(*args, **kwargs)
- self._gaeinitargs = None
- else:
- super(Model, self).__init__(None, None)
- # if Model instances are given in kwargs, turn them into db model
- for key, val in kwargs.iteritems():
- if key in self.e_schema.subject_relations() and not self.e_schema.schema[key].final:
- if isinstance(kwargs, (list, tuple)):
- val = [isinstance(x, Model) and x._dbmodel or x for x in val]
- elif isinstance(val, Model):
- val = val._dbmodel
- kwargs[key] = val.key()
- self._gaeinitargs = (args, kwargs)
-
- def __repr__(self):
- return '<ModelEntity %s %s %s at %s>' % (
- self.e_schema, self.eid, self.keys(), id(self))
-
- def _cubicweb_to_datastore(self, attr, value):
- attr = attr[2:] # remove 's_' / 'o_' prefix
- if attr in self._attributes:
- tschema = self.e_schema.destination(attr)
- if tschema == 'String':
- if len(value) > 500:
- value = Text(value)
- elif tschema == 'Password':
- # if value is a Binary instance, this mean we got it
- # from a query result and so it is already encrypted
- if isinstance(value, Binary):
- value = value.getvalue()
- else:
- value = crypt_password(value)
- elif tschema == 'Bytes':
- if isinstance(value, Binary):
- value = value.getvalue()
- value = Blob(value)
- else:
- value = Key(value)
- return value
-
- def _to_gae_dict(self, convert=True):
- gaedict = {}
- for attr, value in self.iteritems():
- attr = 's_' + attr
- if value is not None and convert:
- value = self._cubicweb_to_datastore(attr, value)
- gaedict[attr] = value
- return gaedict
-
- def to_gae_model(self):
- dbmodel = self._dbmodel
- dbmodel.update(self._to_gae_dict())
- return dbmodel
-
- @property
- @cached
- def _dbmodel(self):
- if self.has_eid():
- assert self._gaeinitargs is None
- try:
- return self.req.datastore_get(self.eid)
- except AttributeError: # self.req is not a server session
- return Get(self.eid)
- self._cw_set_defaults()
- values = self._to_gae_dict(convert=False)
- parent = key_name = _app = None
- if self._gaeinitargs is not None:
- args, kwargs = self._gaeinitargs
- args = list(args)
- if args:
- parent = args.pop(0)
- if args:
- key_name = args.pop(0)
- if args:
- _app = args.pop(0)
- assert not args
- if 'parent' in kwargs:
- assert parent is None
- parent = kwargs.pop('parent')
- if 'key_name' in kwargs:
- assert key_name is None
- key_name = kwargs.pop('key_name')
- if '_app' in kwargs:
- assert _app is None
- _app = kwargs.pop('_app')
-
- for key, value in kwargs.iteritems():
- if key in self._attributes:
- values['s_'+key] = value
- else:
- kwargs = None
- if key_name is None:
- key_name = self.db_key_name()
- if key_name is not None:
- key_name = 'key_' + key_name
- for key, value in values.iteritems():
- if value is None:
- continue
- values[key] = self._cubicweb_to_datastore(key, value)
- entity = Entity(self.id, parent, _app, key_name)
- entity.update(values)
- init_relations(entity, self.e_schema)
- return entity
-
- def db_key_name(self):
- """override this method to control datastore key name that should be
- used at entity creation.
-
- Note that if this function return something else than None, the returned
- value will be prefixed by 'key_' to build the actual key name.
- """
- return None
-
- def metainformation(self):
- return {'type': self.id, 'source': {'uri': 'system'}, 'extid': None}
-
- def view(self, vid, __registry='views', **kwargs):
- """shortcut to apply a view on this entity"""
- return self.vreg[__registry].render(vid, self.req, rset=self.rset,
- row=self.row, col=self.col, **kwargs)
-
- @classmethod
- def _rest_attr_info(cls):
- mainattr, needcheck = super(Model, cls)._rest_attr_info()
- if needcheck:
- return 'eid', False
- return mainattr, needcheck
-
- def get_value(self, name):
- try:
- value = self[name]
- except KeyError:
- if not self.has_eid():
- return None
- value = self._dbmodel.get('s_'+name)
- if value is not None:
- if isinstance(value, Text):
- value = unicode(value)
- elif isinstance(value, Blob):
- value = Binary(str(value))
- self[name] = value
- return value
-
- def has_eid(self):
- if self.eid is None:
- return False
- try:
- Key(self.eid)
- return True
- except BadKeyError:
- return False
-
- def complete(self, skip_bytes=True):
- pass
-
- def unrelated(self, rtype, targettype, role='subject', limit=None,
- ordermethod=None):
- # XXX dumb implementation
- if limit is not None:
- objs = Query(str(targettype)).Get(limit)
- else:
- objs = Query(str(targettype)).Run()
- return rset_from_objs(self.req, objs, ('eid',),
- 'Any X WHERE X is %s' % targettype)
-
- def key(self):
- return Key(self.eid)
-
- def put(self, req=None):
- if req is not None and self.req is None:
- self.req = req
- dbmodel = self.to_gae_model()
- key = Put(dbmodel)
- self.eid = str(key)
- if self.req is not None and self.rset is None:
- self.rset = rset_from_objs(self.req, dbmodel, ('eid',),
- 'Any X WHERE X eid %(x)s', {'x': self.eid})
- self.row = self.col = 0
- return dbmodel
-
- @needrequest
- def get(cls, req, keys):
- # if check if this is a dict.key call
- if isinstance(cls, Model) and keys in cls._attributes:
- return super(Model, cls).get(keys)
- rset = rset_from_objs(req, Get(keys), ('eid',),
- 'Any X WHERE X eid IN %(x)s', {'x': keys})
- return list(rset.entities())
-
- @needrequest
- def get_by_id(cls, req, ids, parent=None):
- if isinstance(parent, Model):
- parent = parent.key()
- ids, multiple = NormalizeAndTypeCheck(ids, (int, long))
- keys = [Key.from_path(cls.kind(), id, parent=parent)
- for id in ids]
- rset = rset_from_objs(req, Get(keys))
- return list(rset.entities())
-
- @classmethod
- def get_by_key_name(cls, req, key_names, parent=None):
- if isinstance(parent, Model):
- parent = parent.key()
- key_names, multiple = NormalizeAndTypeCheck(key_names, basestring)
- keys = [Key.from_path(cls.kind(), name, parent=parent)
- for name in key_names]
- rset = rset_from_objs(req, Get(keys))
- return list(rset.entities())
-
- @classmethod
- def get_or_insert(cls, req, key_name, **kwds):
- def txn():
- entity = cls.get_by_key_name(key_name, parent=kwds.get('parent'))
- if entity is None:
- entity = cls(key_name=key_name, **kwds)
- entity.put()
- return entity
- return RunInTransaction(txn)
-
- @classmethod
- def all(cls, req):
- rset = rset_from_objs(req, Query(cls.id).Run())
- return list(rset.entities())
-
- @classmethod
- def gql(cls, req, query_string, *args, **kwds):
- raise NotImplementedError('use rql')
-
- @classmethod
- def kind(cls):
- return cls.id
-
- @classmethod
- def properties(cls):
- raise NotImplementedError('use eschema')
-
- def dynamic_properties(self):
- raise NotImplementedError('use eschema')
-
- def cw_is_saved(self):
- return self.has_eid()
-
- def parent(self):
- parent = self._dbmodel.parent()
- if not parent is None:
- rset = rset_from_objs(self.req, (parent,), ('eid',),
- 'Any X WHERE X eid %(x)s', {'x': parent.key()})
- parent = rset.get_entity(0, 0)
- return parent
-
- def parent_key(self):
- return self.parent().key()
-
- def to_xml(self):
- return self._dbmodel.ToXml()
-
-# hijack AnyEntity class
-entities.AnyEntity = Model
-
-BooleanProperty = db.BooleanProperty
-URLProperty = db.URLProperty
-DateProperty = db.DateProperty
-DateTimeProperty = db.DateTimeProperty
-TimeProperty = db.TimeProperty
-StringProperty = db.StringProperty
-TextProperty = db.TextProperty
-BlobProperty = db.BlobProperty
-IntegerProperty = db.IntegerProperty
-FloatProperty = db.FloatProperty
-ListProperty = db.ListProperty
-SelfReferenceProperty = db.SelfReferenceProperty
-UserProperty = db.UserProperty
-
-
-class ReferencePropertyStub(object):
- def __init__(self, cls, args, kwargs):
- self.cls = cls
- self.args = args
- self.kwargs = kwargs
- self.required = False
- self.__dict__.update(kwargs)
- self.creation_counter = db.Property.creation_counter
- db.Property.creation_counter += 1
-
- @property
- def data_type(self):
- class FakeDataType(object):
- @staticmethod
- def kind():
- return self.cls.__name__
- return FakeDataType
-
-def ReferenceProperty(cls, *args, **kwargs):
- if issubclass(cls, db.Model):
- cls = db.class_for_kind(cls.__name__)
- return db.ReferenceProperty(cls, *args, **kwargs)
- return ReferencePropertyStub(cls, args, kwargs)
--- a/goa/dbinit.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""some utility functions for datastore initialization.
-
-"""
-__docformat__ = "restructuredtext en"
-
-from google.appengine.api.datastore import Key, Entity, Put, Get, Query
-from google.appengine.api import datastore_errors
-
-_GROUP_CACHE = {} # XXX use memcache
-
-def _get_group(groupname):
- try:
- return _GROUP_CACHE[groupname]
- except KeyError:
- key = Key.from_path('CWGroup', 'key_' + groupname, parent=None)
- try:
- group = Get(key)
- except datastore_errors.EntityNotFoundError:
- raise Exception('can\'t find required group %s, is your instance '
- 'correctly initialized (eg did you run the '
- 'initialization script) ?' % groupname)
- _GROUP_CACHE[groupname] = group
- return group
-
-
-def create_user(login, password, groups):
- """create a cubicweb user"""
- from cubicweb.server.utils import crypt_password
- user = Entity('CWUser', name=login)
- user['s_login'] = unicode(login)
- user['s_upassword'] = crypt_password(password)
- set_user_groups(user, groups)
- Put(user)
- return user
-
-def create_groups():
- """create initial cubicweb groups"""
- for groupname in ('managers', 'users', 'guests'):
- group = Entity('CWGroup', name='key_' + groupname)
- group['s_name'] = unicode(groupname)
- Put(group)
- _GROUP_CACHE[groupname] = group
-
-def set_user_groups(user, groups):
- """set user in the given groups (as string). The given user entity
- (datastore.Entity) is not putted back to the repository, this is the caller
- responsability.
- """
- groups = [_get_group(g) for g in groups]
- user['s_in_group'] = [g.key() for g in groups] or None
- for group in groups:
- try:
- group['o_in_group'].append(user.key())
- except (KeyError, AttributeError):
- group['o_in_group'] = [user.key()]
- Put(group)
-
-def init_relations(gaeentity, eschema):
- """set None for every subject relations which is not yet defined"""
- for rschema in eschema.subject_relations():
- if rschema in ('identity', 'has_text'):
- continue
- dsrelation = 's_' + rschema.type
- if not dsrelation in gaeentity:
- gaeentity[dsrelation] = None
- for rschema in eschema.object_relations():
- if rschema == 'identity':
- continue
- dsrelation = 'o_' + rschema.type
- if not dsrelation in gaeentity:
- gaeentity[dsrelation] = None
-
-def fix_entities(schema):
- for etype in ('CWUser', 'CWGroup'):
- eschema = schema.eschema(etype)
- for gaeentity in Query(etype).Run():
- init_relations(gaeentity, eschema)
- # XXX o_is on CWEType entity
- gaeentity['s_is'] = Key.from_path('CWEType', 'key_' + etype, parent=None)
- Put(gaeentity)
-
-def init_persistent_schema(ssession, schema):
- execute = ssession.execute
- rql = ('INSERT CWEType X: X name %(name)s, X description %(descr)s,'
- 'X final FALSE')
- eschema = schema.eschema('CWEType')
- execute(rql, {'name': u'CWEType', 'descr': unicode(eschema.description)})
- for eschema in schema.entities():
- if eschema.final or eschema == 'CWEType':
- continue
- execute(rql, {'name': unicode(eschema),
- 'descr': unicode(eschema.description)})
-
-def insert_versions(ssession, config):
- execute = ssession.execute
- # insert versions
- execute('INSERT CWProperty X: X pkey %(pk)s, X value%(v)s',
- {'pk': u'system.version.cubicweb',
- 'v': unicode(config.cubicweb_version())})
- for cube in config.cubes():
- execute('INSERT CWProperty X: X pkey %(pk)s, X value%(v)s',
- {'pk': u'system.version.%s' % cube,
- 'v': unicode(config.cube_version(cube))})
--- a/goa/dbmyams.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,223 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""extends yams to be able to load google appengine's schemas
-
-MISSING FEATURES:
- - ListProperty, StringList, EmailProperty, etc. (XXX)
- - ReferenceProperty.verbose_name, collection_name, etc. (XXX)
-
-XXX proprify this knowing we'll use goa.db
-"""
-
-from os.path import join
-from datetime import datetime, date, time
-
-from google.appengine.ext import db
-from google.appengine.api import datastore_types
-
-from yams.buildobjs import (String, Int, Float, Boolean, Date, Time, Datetime,
- Bytes, SubjectRelation)
-from yams.buildobjs import metadefinition, EntityType
-
-from cubicweb.schema import CubicWebSchemaLoader
-from cubicweb.goa import db as goadb
-
-# db.Model -> yams ############################################################
-
-DBM2Y_TYPESMAP = {
- basestring: String,
- datastore_types.Text: String,
- int: Int,
- float: Float,
- bool: Boolean,
- time: Time,
- date: Date,
- datetime: Datetime,
- datastore_types.Blob: Bytes,
- }
-
-
-def dbm2y_default_factory(prop, **kwargs):
- """just wraps the default types map to set
- basic constraints like `required`, `default`, etc.
- """
- yamstype = DBM2Y_TYPESMAP[prop.data_type]
- if 'default' not in kwargs:
- default = prop.default_value()
- if default is not None:
- kwargs['default'] = default
- if prop.required:
- kwargs['required'] = True
- return yamstype(**kwargs)
-
-def dbm2y_string_factory(prop):
- """like dbm2y_default_factory but also deals with `maxsize` and `vocabulary`"""
- kwargs = {}
- if prop.data_type is basestring:
- kwargs['maxsize'] = 500
- if prop.choices is not None:
- kwargs['vocabulary'] = prop.choices
- return dbm2y_default_factory(prop, **kwargs)
-
-def dbm2y_date_factory(prop):
- """like dbm2y_default_factory but also deals with today / now definition"""
- kwargs = {}
- if prop.auto_now_add:
- if prop.data_type is datetime:
- kwargs['default'] = 'now'
- else:
- kwargs['default'] = 'today'
- # XXX no equivalent to Django's `auto_now`
- return dbm2y_default_factory(prop, **kwargs)
-
-
-def dbm2y_relation_factory(etype, prop, multiple=False):
- """called if `prop` is a `db.ReferenceProperty`"""
- if multiple:
- cardinality = '**'
- elif prop.required:
- cardinality = '1*'
- else:
- cardinality = '?*'
- # XXX deal with potential kwargs of ReferenceProperty.__init__()
- try:
- return SubjectRelation(prop.data_type.kind(), cardinality=cardinality)
- except AttributeError, ex:
- # hack, data_type is still _SELF_REFERENCE_MARKER
- return SubjectRelation(etype, cardinality=cardinality)
-
-
-DBM2Y_FACTORY = {
- basestring: dbm2y_string_factory,
- datastore_types.Text: dbm2y_string_factory,
- int: dbm2y_default_factory,
- float: dbm2y_default_factory,
- bool: dbm2y_default_factory,
- time: dbm2y_date_factory,
- date: dbm2y_date_factory,
- datetime: dbm2y_date_factory,
- datastore_types.Blob: dbm2y_default_factory,
- }
-
-
-class GaeSchemaLoader(CubicWebSchemaLoader):
- """Google appengine schema loader class"""
- def __init__(self, *args, **kwargs):
- self.use_gauthservice = kwargs.pop('use_gauthservice', False)
- super(GaeSchemaLoader, self).__init__(*args, **kwargs)
- self.defined = {}
- self.created = []
- self.loaded_files = []
- self._instantiate_handlers()
-
- def finalize(self, register_base_types=False):
- return self._build_schema('google-appengine', register_base_types)
-
- def load_dbmodel(self, name, props):
- clsdict = {}
- ordered_props = sorted(props.items(),
- key=lambda x: x[1].creation_counter)
- for pname, prop in ordered_props:
- if isinstance(prop, db.ListProperty):
- if not issubclass(prop.item_type, db.Model):
- self.error('ignoring list property with %s item type'
- % prop.item_type)
- continue
- rdef = dbm2y_relation_factory(name, prop, multiple=True)
- else:
- try:
- if isinstance(prop, (db.ReferenceProperty,
- goadb.ReferencePropertyStub)):
- rdef = dbm2y_relation_factory(name, prop)
- else:
- rdef = DBM2Y_FACTORY[prop.data_type](prop)
- except KeyError, ex:
- import traceback
- traceback.print_exc()
- self.error('ignoring property %s (keyerror on %s)' % (pname, ex))
- continue
- rdef.creation_rank = prop.creation_counter
- clsdict[pname] = rdef
- edef = metadefinition(name, (EntityType,), clsdict)
- self.add_definition(self, edef())
-
- def error(self, msg):
- print 'ERROR:', msg
-
- def import_yams_schema(self, ertype, schemamod):
- erdef = self.pyreader.import_erschema(ertype, schemamod)
-
- def import_yams_cube_schema(self, templpath):
- for filepath in self.get_schema_files(templpath):
- self.handle_file(filepath)
-
- @property
- def pyreader(self):
- return self._live_handlers['.py']
-
-import os
-from cubicweb import CW_SOFTWARE_ROOT
-
-def load_schema(config, schemaclasses=None, extrahook=None):
- """high level method to load all the schema for a lax instance"""
- # IMPORTANT NOTE: dbmodel schemas must be imported **BEFORE**
- # the loader is instantiated because this is where the dbmodels
- # are registered in the yams schema
- for compname in config['included-cubes']:
- __import__('%s.schema' % compname)
- loader = GaeSchemaLoader(use_gauthservice=config['use-google-auth'], db=db)
- if schemaclasses is not None:
- for cls in schemaclasses:
- loader.load_dbmodel(cls.__name__, goadb.extract_dbmodel(cls))
- elif config['schema-type'] == 'dbmodel':
- import schema as appschema
- for obj in vars(appschema).values():
- if isinstance(obj, type) and issubclass(obj, goadb.Model) and obj.__module__ == appschema.__name__:
- loader.load_dbmodel(obj.__name__, goadb.extract_dbmodel(obj))
- for erschema in ('CWGroup', 'CWEType', 'CWRType', 'RQLExpression',
- 'is_', 'is_instance_of',
- 'read_permission', 'add_permission',
- 'delete_permission', 'update_permission'):
- loader.import_yams_schema(erschema, 'bootstrap')
- loader.handle_file(join(CW_SOFTWARE_ROOT, 'schemas', 'base.py'))
- cubes = config['included-yams-cubes']
- for cube in reversed(config.expand_cubes(cubes)):
- config.info('loading cube %s', cube)
- loader.import_yams_cube_schema(config.cube_dir(cube))
- if config['schema-type'] == 'yams':
- loader.import_yams_cube_schema('.')
- if extrahook is not None:
- extrahook(loader)
- if config['use-google-auth']:
- loader.defined['CWUser'].remove_relation('upassword')
- loader.defined['CWUser'].permissions['add'] = ()
- loader.defined['CWUser'].permissions['delete'] = ()
- for etype in ('CWGroup', 'RQLExpression'):
- read_perm_rel = loader.defined[etype].get_relations('read_permission').next()
- read_perm_rel.cardinality = '**'
- # XXX not yet ready for CWUser workflow
- loader.defined['CWUser'].remove_relation('in_state')
- loader.defined['CWUser'].remove_relation('wf_info_for')
- # remove RQLConstraint('NOT O name "owners"') on CWUser in_group CWGroup
- # since "owners" group is not persistent with gae
- loader.defined['CWUser'].get_relations('in_group').next().constraints = []
- # return the full schema including the cubes' schema
- for ertype in loader.defined.values():
- if getattr(ertype, 'inlined', False):
- ertype.inlined = False
- return loader.finalize()
--- a/goa/doc/FAQ.en.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-==============================
-LAX Frequently Asked Questions
-==============================
-
-[WRITE ME]
\ No newline at end of file
--- a/goa/doc/README_LAX.fr.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-Qu'est-ce que ``LAX`` ?
-=======================
-
-``LAX`` (Logilab Application engine eXtension) est un framework
-d'application web qui facilite les développements faits pour
-``Google AppEngine``.
-
-``LAX`` est un portage de la partie web de la plate-forme
-applicative développée par Logilab depuis 2001. Cette plate-forme
-publie des données que la partie stockage tire de bases SQL,
-d'annuaires LDAP et de systèmes de gestion de version. Depuis mai
-2008, elle fonctionne sur le "datastore" de ``Google AppEngine``.
-
-``LAX`` est pour le moment en version alpha.
-
-Django/GAE vs. LAX/GAE
-=======================
-
-NotImplementedError()
-
-
-Téléchargement des sources
-==========================
-
-- Les sources de ``Google AppEngine`` peuvent être obtenues à l'adresse
- suivante : http://code.google.com/appengine/downloads.html
-
-- Les sources de ``LAX`` se trouvent à l'adresse suivante :
- http://lax.logilab.org/
-
-
-Installation
-============
-
-Les sources de ``Google AppEngine`` doivent être décompressées et le
-répertoire `google` qui s'y trouve doit être accessible par la variable
-d'environnement ``PYTHONPATH``. Correctement définir le ``PYTHONPATH``
-n'est pas nécessaire pour le lancement de l'application elle-même mais
-pour l'utilisation des scripts fournis par ``LAX`` ou pour l'exécution
-des tests unitaires.
-
-Une fois décompactée, l'archive ``lax-0.1.0-alpha.tar.gz``, on obtient
-l'arborescence suivante::
-
- .
- |-- app.yaml
- |-- custom.py
- |-- data
- |-- cubicweb/
- |-- i18n/
- |-- logilab/
- |-- main.py
- |-- mx/
- |-- rql/
- |-- schema.py
- |-- simplejson/
- |-- tools/
- | |-- generate_schema_img.py
- | `-- i18ncompile.py
- |-- views.py
- |-- yams/
- `-- yapps/
-
-
-On retrouve le squelette d'une application web de ``Google AppEngine``
-(fichiers ``app.yaml``, ``main.py``en particulier) avec les dépendances
-supplémentaires nécessaires à l'utilisation du framework ``LAX``
-
-
-Lancement de l'application de base
-==================================
-
-python /path/to/google_appengine/dev_appserver.py /path/to/lax
-
-
--- a/goa/doc/devmanual_fr/advanced_notes.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-
-La différence entre la classe `AppRsetObject` et la classe `AppObject` est que
-les instances de la premières sont séléctionnées pour une requête et un "result
-set" et alors que les secondes ne sont séléctionnées qu'en fonction de leur
-identifiant.
Binary file goa/doc/devmanual_fr/archi_globale.dia has changed
Binary file goa/doc/devmanual_fr/archi_globale.png has changed
--- a/goa/doc/devmanual_fr/chap_autres_composants_ui.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-Autres composants de l'interface web
-====================================
-
-Actions
--------
-XXXFILLME
-
-Component, VComponent
----------------------
-XXXFILLME
-
-CWProperty
----------
-XXXFILLME
--- a/goa/doc/devmanual_fr/chap_bases_framework_erudi.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,226 +0,0 @@
-Fondements du framework CubicWeb
-=============================
-
-Le moteur web d'cubicweb consiste en quelques classes gérant un ensemble d'objets
-chargés dynamiquement au lancement d'cubicweb. Ce sont ces objets dynamiques, issus
-du modèle ou de la librairie, qui construisent le site web final. Les différents
-composants dynamiques sont par exemple :
-
-* coté client et serveur
-
- - les définitions d'entités, contenant la logique permettant la manipulation des
- données de l'application
-
-* coté client
-
- - les *vues* , ou encore plus spécifiquement
-
- - les boites
- - l'en-tête et le pied de page
- - les formulaires
- - les gabarits de pages
-
- - les *actions*
- - les *controleurs*
-
-* coté serveur
-
- - les crochets de notification
- - les vues de notification
-
-Les différents composants du moteur sont :
-
-* un frontal web (seul twisted disponible pour le moment), transparent du point
- de vue des objets dynamiques
-* un objet encapsulant la configuration
-* un `vregistry` (`cubicweb.cwvreg`) contenant les objets chargés dynamiquements
-
-
-Détail de la procédure d'enregistrement
----------------------------------------
-Au démarage le `vregistry` ou base de registres inspecte un certain nombre de
-répertoires à la recherche de définition de classes "compatible". Après une
-procédure d'enregistrement les objets sont affectés dans différents registres
-afin d'être ensuite séléctionné dynamiquement pendant le fonctionnement de
-l'application.
-
-La classe de base de tout ces objets est la classe `AppRsetObject` (module
-`cubicweb.common.appobject`).
-
-
-API Python/RQL
---------------
-
-Inspiré de la db-api standard, avec un object Connection possédant les méthodes
-cursor, rollback et commit principalement. La méthode importante est la méthode
-`execute` du curseur :
-
-`execute(rqlstring, args=None, eid_key=None, build_descr=True)`
-
-:rqlstring: la requête rql à éxécuter (unicode)
-:args: si la requête contient des substitutions, un dictionnaire contenant les
- valeurs à utiliser
-:eid_key:
- un détail d'implémentation du cache de requêtes RQL fait que si une substitution est
- utilisée pour introduire un eid *levant des ambiguités dans la résolution de
- type de la requête*, il faut spécifier par cet argument la clé correspondante
- dans le dictionnaire
-
-C'est l'objet Connection qui possède les méthodes classiques `commit` et
-`rollback`. Vous ne *devriez jamais avoir à les utiliser* lors du développement
-d'interface web sur la base du framework CubicWeb étant donné que la fin de la
-transaction est déterminée par celui-ci en fonction du succès d'éxécution de la
-requête.
-
-NOTE : lors de l'éxécution de requêtes de modification (SET,INSERT,DELETE), si une
-requête génère une erreur liée à la sécurité, un rollback est systématiquement
-effectuée sur la transaction courante.
-
-
-La classe `Request` (`cubicweb.web`)
----------------------------------
-Une instance de requête est créée lorsque une requête HTTP est transmise au
-serveur web. Elle contient des informations telles que les paramètres de
-formulaires, l'utilisateur connecté, etc.
-
-**De manière plus générale une requête représente une demande d'un utilisateur,
-que se soit par HTTP ou non (on parle également de requête rql coté serveur par
-exemple)**
-
-Une instance de la classe `Request` possède les attributs :
-
-* `user`, instance de`cubicweb.common.utils.User` correspondant à l'utilisateur
- connecté
-* `form`, dictionaire contenant les valeurs de formulaire web
-* `encoding`, l'encodage de caractère à utiliser dans la réponse
-
-Mais encore :
-
-:Gestion des données de session:
- * `session_data()`, retourne un dictionaire contenant l'intégralité des
- données de la session
- * `get_session_data(key, default=None)`, retourne la valeur associée à
- la clé ou la valeur `default` si la clé n'est pas définie
- * `set_session_data(key, value)`, associe une valeur à une clé
- * `del_session_data(key)`, supprime la valeur associé à une clé
-
-
-:Gestion de cookie:
- * `get_cookie()`, retourne un dictionnaire contenant la valeur de l'entête
- HTTP 'Cookie'
- * `set_cookie(cookie, key, maxage=300)`, ajoute un en-tête HTTP `Set-Cookie`,
- avec une durée de vie 5 minutes par défault (`maxage` = None donne un cooke
- *de session"* expirant quand l'utilisateur ferme son navigateur
- * `remove_cookie(cookie, key)`, fait expirer une valeur
-
-:Gestion d'URL:
- * `url()`, retourne l'url complète de la requête HTTP
- * `base_url()`, retourne l'url de la racine de l'application
- * `relative_path()`, retourne chemin relatif de la requête
-
-:Et encore...:
- * `set_content_type(content_type, filename=None)`, place l'en-tête HTTP
- 'Content-Type'
- * `get_header(header)`, retourne la valeur associé à un en-tête HTTP
- arbitraire de la requête
- * `set_header(header, value)`, ajoute un en-tête HTTP arbitraire dans la
- réponse
- * `cursor()` retourne un curseur RQL sur la session
- * `execute(*args, **kwargs)`, raccourci vers .cursor().execute()
- * `property_value(key)`, gestion des propriétés (`CWProperty`)
- * le dictionaire `data` pour stocker des données pour partager de
- l'information entre les composants *durant l'éxécution de la requête*.
-
-A noter que cette classe est en réalité abstraite et qu'une implémentation
-concrète sera fournie par le *frontend* web utilisé (en l'occurent *twisted*
-aujourd'hui). Enfin pour les vues ou autres qui sont éxécutés coté serveur,
-la majeure partie de l'interface de `Request` est définie sur la session
-associée au client.
-
-
-La classe `AppObject`
----------------------
-
-En général :
-
-* on n'hérite pas directement des cette classe mais plutôt d'une classe
- plus spécifique comme par exemple `AnyEntity`, `EntityView`, `AnyRsetView`,
- `Action`...
-
-* pour être enregistrable, un classe fille doit définir son registre (attribut
- `__registry__`) et son identifiant (attribut `id`). Généralement on n'a pas à
- s'occuper du registre, uniquement de l'identifiant `id` :)
-
-On trouve un certain nombre d'attributs et de méthodes définis dans cette classe
-et donc commune à tous les objets de l'application :
-
-A l'enregistrement, les attributs suivants sont ajoutés dynamiquement aux
-*classes* filles:
-
-* `vreg`, le `vregistry` de l'application
-* `schema`, le schéma de l'application
-* `config`, la configuration de l'application
-
-On trouve également sur les instances les attributs :
-
-* `req`, instance de `Request`
-* `rset`, le "result set" associé à l'objet le cas échéant
-* `cursor`, curseur rql sur la session
-
-
-:Gestion d'URL:
- * `build_url(method=None, **kwargs)`, retourne une URL absolue construites à
- partir des arguments donnés. Le *controleur* devant gérer la réponse
- peut-être spécifié via l'argument spécial `method` (le branchement est
- théoriquement bien effectué automatiquement :).
-
- * `datadir_url()`, retourne l'url du répertoire de données de l'application
- (contenant les fichiers statiques tels que les images, css, js...)
-
- * `base_url()`, raccourci sur `req.base_url()`
-
- * `url_quote(value)`, version *unicode safe* de de la fonction `urllib.quote`
-
-:Manipulation de données:
-
- * `etype_rset(etype, size=1)`, raccourci vers `vreg.etype_rset()`
-
- * `eid_rset(eid, rql=None, descr=True)`, retourne un objet result set pour
- l'eid donné
- * `entity(row, col=0)`, retourne l'entité correspondant à la position données
- du "result set" associé à l'objet
-
- * `complete_entity(row, col=0, skip_bytes=True)`, équivalent à `entity` mais
- appelle également la méthode `complete()` sur l'entité avant de la retourner
-
-:Formattage de données:
- * `format_date(date, date_format=None, time=False)`
- * `format_time(time)`,
-
-:Et encore...:
-
- * `external_resource(rid, default=_MARKER)`, accède à une valeur définie dans
- le fichier de configuration `external_resource`
-
- * `tal_render(template, variables)`,
-
-
-**NOTE IMPORTANTE**
-Lorsqu'on hérite d'`AppObject` (même indirectement), il faut **toujours**
-utiliser **super()** pour récupérer les méthodes et attributs des classes
-parentes, et pas passer par l'identifiant de classe parente directement.
-(sous peine de tomber sur des bugs bizarres lors du rechargement automatique
-des vues). Par exemple, plutôt que d'écrire::
-
- class Truc(PrimaryView):
- def f(self, arg1):
- PrimaryView.f(self, arg1)
-
-Il faut écrire::
-
- class Truc(PrimaryView):
- def f(self, arg1):
- super(Truc, self).f(arg1)
-
-
-XXX FILLME diagramme interaction application/controller/template/view
--- a/goa/doc/devmanual_fr/chap_configuration_instance.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-Configuration d'une instance
-============================
-
-À la création d'une instance, un fichier de configuration est généré dans ::
-
- $(CW_REGISTRY)/<instance>/<nom configuration>.conf
-
-par exemple ::
-
- /etc/cubicweb.d/jpl/all-in-one.conf
-
-C'est un simple fichier texte au format INI. Dans la description suivante,
-chaque nom d'option est préfixé de sa section et suivi de sa valeur par défaut
-le cas échéant, e.g. "`<section>.<option>` [valeur]".
-
-
-Configuration du serveur web
-----------------------------
-:`web.auth-mode` [cookie]:
- mode d'authentification, cookie ou http
-:`web.realm`:
- realm de l'application en mode d'authentification http
-:`web.http-session-time` [0]:
- délai d'inactivité d'une session HTTP avant sa fermeture automatique. Durée
- en secondes, 0 signifiant pas d'expiration (ou plus exactement lors de la
- fermeture du navigateur du client)
-
-:`main.anonymous-user`, `main.anonymous-password`:
- login et mot de passe à utiliser pour se connecter au serveur RQL lors des
- connexions HTTP anonymes. Il faut que le compte CWUser associé existe.
-
-:`main.base-url`:
- url de base du site, à utiliser pour générer les urls des pages web
-
-Configuration https
-```````````````````
-Il est possible de rendre un site accessible en http pour les connections
-anonymes et en https pour les utilisateurs authentifié. Il faut pour cela
-utiliser apache (par ex.) pour la redirection et la variable `main.https-url` du
-fichier de configuration.
-
-:Exemple:
-
- pour une redirection apache d'un site accessible via `http://localhost/demo`
- et `https://localhost/demo` et qui tourne en réalité sur le port 8080, il
- faut avoir pour la version http : ::
-
- RewriteCond %{REQUEST_URI} ^/demo
- RewriteRule ^/demo$ /demo/
- RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
-
- et pour la version https : ::
-
- RewriteCond %{REQUEST_URI} ^/demo
- RewriteRule ^/demo$ /demo/
- RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
-
-
- et on aura dans le fichier all-in-one.conf de l'instance : ::
-
- base-url = http://localhost/demo
- https-url = `https://localhost/demo`
-
-Configuration de l'interface web
---------------------------------
-:`web.embed-allowed`:
- expression régulière correspondant aux sites pouvant être "incorporé" dans
- le site (controleur 'embed')
-:`web.submit-url`:
- url à laquelle les bugs rencontrés dans l'application peuvent être posté
-
-
-Configuration du serveur RQL
-----------------------------
-:`main.host`:
- nom de l'hôte s'il ne peut être détecter correctement
-:`main.pid-file`:
- fichier où sera écrit le pid du serveur
-:`main.uid`:
- compte utilisateur à utiliser pour le lancement du serveur quand il est
- lancé en root par init
-:`main.session-time [30*60]`:
- temps d'expiration d'une session RQL
-:`main.query-log-file`:
- fichier dans lequel écrire toutes les requêtes RQL éxécutées par le serveur
-
-
-Configuration Pyro pour l'instance
------------------------------------
-Coté serveur web :
-
-:`pyro-client.pyro-application-id`:
- identifiant pyro du serveur RQL (e.g. le nom de l'instance)
-
-Coté serveur RQL :
-
-:`pyro-server.pyro-port`:
- numéro de port pyro. Si aucune valeur n'est spécifiée, un port est attribué
- automatiquement.
-
-Coté serveur RQL et serveur web :
-
-:`pyro-name-server.pyro-ns-host`:
- nom de l'hôte hébergeant le serveur de nom pyro. Si aucune valeur n'est
- spécifié, il est localisé par une requête de broadcast
-:`pyro-name-server.pyro-ns-group` [cubicweb]:
- groupe pyro sous lequel enregistrer l'application
-
-
-Configuration courriel
-----------------------
-Coté serveur RQL et serveur web :
-
-:`email.mangle-emails [no]`:
- indique si les adresses email doivent être affichées telle quelle ou
- transformée
-
-Coté serveur RQL :
-
-:`email.smtp-host [mail]`:
- nom de l'hôte hébergeant le serveur SMTP à utiliser pour le courriel sortant
-:`email.smtp-port [25]`:
- port du serveur SMTP à utiliser pour le courriel sortant
-:`email.sender-name`:
- nom à utiliser pour les courriels sortant de l'application
-:`email.sender-addr`:
- adresse à utiliser pour les courriels sortant de l'application
-:`email.default-dest-addrs`:
- adresses de destination par défaut, si utilisé par la configuration de la
- diffusion du modèle (séparées par des virgules)
-:`email.supervising-addrs`:
- addresses de destination des courriels de supervision (séparées par des
- virgules)
-
-
-Configuration journalisation
-----------------------------
-:`main.log-threshold`:
- niveau de filtrage des messages (DEBUG, INFO, WARNING, ERROR)
-:`main.log-file`:
- fichier dans lequel écrire les messages
-
-
-Configuration Eproperties
--------------------------
-D'autres paramètres de configuration sont sous la forme d'entités `CWProperty`
-dans la base de données. Il faut donc les éditer via l'interface web ou par des
-requêtes rql.
-
-:`ui.encoding`:
- encodage de caractères à utiliser pour l'interface web
-:`navigation.short-line-size`: # XXX should be in ui
- nombre de caractères maximum pour les affichages "courts"
-:`navigation.page-size`:
- nombre d'entités maximum à afficher par page de résultat
-:`navigation.related-limit`:
- nombre d'entités liées maximum à afficher sur la vue primaire d'une entité
-:`navigation.combobox-limit`:
- nombre d'entités non liées maximum à afficher sur les listes déroulantes de
- la vue d'édition d'une entité
--- a/goa/doc/devmanual_fr/chap_definition_schema.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-Définition du modèle de données (*schéma*)
-==========================================
-
-Le schéma est l'élément central d'une application d'CubicWeb, définissant le modèle
-de données manipulé. Il est généralement défini à partir de type d'entités
-existants dans la librairie et d'autres spécifiques, généralement décrites dans
-un ou plusieurs fichiers python dans le sous-répertoire `schema` du modèle.
-
-A ce niveau il est important de noter la différence entre type de relation et
-définition de relation : un type de relation est uniquement un nom de relation
-avec éventuellement quelques propriétés supplémentaires (voir plus bas), alors
-qu'une définition de relation est un triplet complet "<type d'entité sujet>
-<type de relation> <type d'entité objet>". Eventuellement un type de relation
-sera créé implicitement si aucun n'est associé à une définition de relation du
-schema.
-
-.. include:: sect_stdlib_schemas.txt
-.. include:: sect_definition_schema.txt
-
--- a/goa/doc/devmanual_fr/chap_definition_workflows.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-Définition de workflow
-======================
-On peut mettre une condition rql ou/et un groupe auquel doit appartenir l'utilisateur.
-
-Si on met à la fois un(ou plusieurs) groupe et une condition RQL, il faut que les deux soient respectés.
-
-Si on met plusieurs groupes, il faut que l'utilisateur soit dans un des groupes.
-
-Pour la condition RQL sur une transition, on peut y mettre les substitutions suivantes :
-
-* `%(eid)s`, eid de l'objet
-* `%(ueid)s`, eid de l'utilisateur qui fait la requête
-* `%(seid)s`, eid de l'état courant de l'objet
-
-Dans le script de création d'un workflow, penser à mettre `_()` autour des noms d'états et de transitions
-pour que ceux si soient pris en compte par les scripts de gestion des catalogues i18n.
\ No newline at end of file
--- a/goa/doc/devmanual_fr/chap_fondements_erudi.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-Fondements CubicWeb
-================
-
-Concepts et vocabulaire
------------------------
-
-*schéma*
- le schéma définit le modèle de données d'une application sous forme d'entités
- et de relations, grâce au package `yams`_. C'est l'élément central d'une
- application. Il est initialement défini sur le système de fichiers et est
- stocké dans la base de données lors de la création d'une instance. CubicWeb
- fournit un certain nombres de types d'entités inclus systématiquement
- car nécessaire au noyau CubicWeb et une librairie de composants devant être
- inclus explicitement le cas échéant.
-
-*source*
- une source de données est un conteneur de données quelquonque (SGBD, annuaire
- LDAP...) intégré par l'entrepôt CubicWeb. Un entrepôt possède au moins une source
- dite "system" contenant le schéma de l'application, l'index plein-texte et
- d'autres informations vitales au système.
-
-*composant*
- un composant est un modèle regroupant un ou plusieurs types de données et/ou
- des vues afin de fournir une fonctionalité précise, ou une application CubicWeb
- complète utilisant éventuellement d'autres composants. Les différents
- composants disponibles sur une machine sont installés dans
- `/usr/share/cubicweb/templates`
-
-*result set*
- objet encaspulant les résultats d'une requête RQL et des informations sur
- cette requête.
-
-.. _`Python Remote Object`: http://pyro.sourceforge.net/
-.. _`yams`: http://www.logilab.org/project/name/yams/
-
-
-Structure générale d'une application LAX
-----------------------------------------
-
-Un composant complexe est structuré selon le modèle suivant :
-
-::
-
- .
- |-- app.yaml
- |-- custom.py
- |-- data
- |-- cubicweb/
- |-- i18n/
- |-- logilab/
- |-- main.py
- |-- mx/
- |-- rql/
- |-- schema.py
- |-- simplejson/
- |-- tools/
- | |-- generate_schema_img.py
- | `-- i18ncompile.py
- |-- views.py
- |-- yams/
- `-- yapps/
-
-
-où :
-
-* ``schema.py`` contient la définition du schéma
-* ``views.py`` contient les définitions des vues
-* ``i18n`` contient les catalogues de messages pour les langues supportées (coté
- serveur et interface web)
-* ``data`` contient des fichiers de données arbitraires servis statiquement
- (images, css, fichiers javascripts)... (coté interface web uniquement)
--- a/goa/doc/devmanual_fr/chap_i18n.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-Internationalisation
-====================
-
-Le système d'internationalisation de l'interface web d'cubicweb est basé sur le
-système `GNU gettext`_.
-
-.. _`GNU gettext`: http://www.gnu.org/software/gettext/
-
-Messages à internationaliser
-----------------------------
-
-Marquage des messages à internaliser
-````````````````````````````````````
-Les chaines de caractères à internationaliser sont marqués par l'appel à la
-fonction `_` *OU* par la méthode équivalent de la requête dans le code python ou
-dans les expressions python de template TAL.
-
-Dans les templates cubicweb-tal, il est également possible d'insérer une chaine à
-traduire via les balises `i18n:content` et `i18n:replace`.
-
-De plus des messages correspondant aux entités/relations utilisés par le schéma
-de l'application seront automatiquement ajoutés.
-
-Renvoi d'un message internationalisé lors de la construction d'une page
-```````````````````````````````````````````````````````````````````````
-La fonction *built-in* `_` ne doit servir qu'**à marquer les messages à
-traduire**, non pas à récupérer une traduction. Il faut pour cela utiliser la
-méthode `_` de l'objet requête, sans quoi vous récupérerez l'identifiant de
-message au lieu de sa traduction dans la langue propre à la requête.1
-
-
-Gestion des catalogues de traduction
-------------------------------------
-Une fois l'application rendu internationalisable coté code, reste à gérer les
-catalogues de traductions. cubicweb-ctl intègre pour cela les commandes suivantes :
-
-* `i18ncubicweb`, met à jour les catalogues de messages *de la librairie
- cubicweb*. Sauf si vous développez sur le framework (et non votre propre
- application), vous ne devriez pas avoir à utiliser cette commande
-
-* `i18ncube`, met à jour les catalogues de messages *du composant* (ou de tous
- les composants). A la suite de cette commande, vous devez mettre à jour les
- fichiers de traduction *.po* dans le sous-répertoire "i18n" de votre
- template. Évidemment les traductions précédentes toujours utilisées ont été
- conservées.
-
-* `i18ninstance`, recompile les catalogues de messages *d'une instance* (ou de
- toutes les instances) après mise à jour des catalogues de son composant. Cela
- est effectué automatiquement lors d'une création ou d'une mise à jour. Les
- catalogues de messages compilés se trouvent dans le répertoire
- "i18n/<lang>/LC_MESSAGES/cubicweb.mo" de l'application où `lang` est
- l'identifiant de la langue sur 2 lettres ('en' ou 'fr' par exemple)
-
-
-Le cas classique
-````````````````
-Vous avez ajouté et/ou modifié des messages d'un composant utilisé par votre
-application (en ajoutant une nouvelle vue ou en ayant modifié le schéma par
-exemple) :
-
-1. `cubicweb-ctl i18ncube <composant>`
-2. éditer les fichiers <composant>/xxx.po dans pour y rajouter les traductions
- manquantes (`msgstr` vide)
-3. `hg ci -m "updated i18n catalogs"`
-4. `cubicweb-ctl i18ninstance <monapplication>`
-
--- a/goa/doc/devmanual_fr/chap_manipulation_donnees.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-Manipulation des données stockées
-=================================
-
-Les classes `Entity` et `AnyEntity`
------------------------------------
-Pour fournir un comportement spécifique à un type d'entité, il suffit de définir
-une classe héritant de la class `cubicweb.entities.AnyEntity`. En général il faut
-définir ces classes dans un module du package `entities` d'une application pour
-qu'elle soit disponible à la fois coté serveur et coté client.
-
-La classe `AnyEntity` est une classe chargée dynamiquement héritant de la classe
-de base `Entity` (`cubicweb.common.entity`). On définit une sous-classe pour
-ajouter des méthodes ou spécialiser les comportements d'un type d'entité donné.
-
-Des descripteurs sont ajoutés à l'enregistrement pour initialiser la classe en
-fonction du schéma :
-
-* on peut accéder aux attributs définis dans le schéma via les attributs de même
- nom sur les instances (valeur typée)
-
-* on peut accéder aux relations définies dans le schéma via les attributs de même
- nom sur les instances (liste d'instances d'entité)
-
-Les méthodes définies sur la classe `AnyEntity` ou `Entity` sont les suivantes :
-
-* `has_eid()`, retourne vrai si l'entité à un eid affecté (i.e. pas en cours de
- création)
-
-* `check_perm(action)`, vérifie que l'utilisateur à le droit d'effectuer
- l'action demandée sur l'entité
-
-:Formattage et génération de la sortie:
-
- * `view(vid, **kwargs)`, applique la vue donnée à l'entité
-
- * `absolute_url(**kwargs)`, retourne une URL absolue permettant d'accéder à la
- vue primaire d'une entité
-
- * `format(attr)`, retourne le format (type MIME) du champ passé en argument
-
- * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`,
- retourne une chaine permettant l'affichage dans un format donné de la valeur
- d'un attribut (la valeur est automatiquement récupérée au besoin)
-
- * `display_name(form='')`, retourne une chaîne pour afficher le type de
- l'entité, en spécifiant éventuellement la forme désirée ('plural' pour la
- forme plurielle)
-
-:Gestion de données:
-
- * `complete(skip_bytes=True)`, effectue une requête permettant de récupérer d'un
- coup toutes les valeurs d'attributs manquant sur l'entité
-
- * `get_value(name)`, récupere la valeur associée à l'attribut passé en argument
-
- * `related(rtype, x='subject', limit=None, entities=False)`, retourne une liste
- des entités liées à l'entité courant par la relation donnée en argument
-
- * `unrelated(rtype, targettype, x='subject', limit=None)`, retourne un result set
- des entités not liées à l'entité courante par la relation donnée en argument
- et satisfaisants les contraintes de celle-ci
-
- * `copy_relations(ceid)`, copie les relations de l'entité ayant l'eid passé en
- argument sur l'entité courante
-
- * `last_modified(view)`, retourne la date à laquelle on doit considérer
- l'objet comme modifié (utiliser par la gestion de cache HTTP)
-
-:Meta-données standard (Dublin Core):
-
- * `dc_title()`, retourne une chaine unicode correspondant à la méta-donnée
- 'Title' (utilise par défaut le premier attribut non 'meta' du schéma de
- l'entité)
-
- * `dc_long_title()`, comme dc_title mais peut retourner un titre plus détaillé
-
- * `dc_description(format='text/plain')`, retourne une chaine unicode
- correspondant à la méta-donnée 'Description' (cherche un attribut
- 'description' par défaut)
-
- * `dc_authors()`, retourne une chaine unicode correspondant à la méta-donnée
- 'Authors' (propriétaires par défaut)
-
- * `dc_date(date_format=None)`, retourne une chaine unicode
- correspondant à la méta-donnée 'Date' (date de modification par défaut)
-
-:Contrôle du vocabulaire pour les relations:
- * `vocabulary(rtype, x='subject', limit=None)`
- * `subject_relation_vocabulary(rtype, limit=None)`
- * `object_relation_vocabulary(rtype, limit=None)`
- * `relation_vocabulary(rtype, targettype, x, limit=None)`
-
-
-Les *rtags*
------------
-Les *rtags* permettent de spécifier certains comportements propres aux relations
-d'un type d'entité donné (voir plus loin). Ils sont définis sur la classe
-d'entité via l'attribut `rtags` qui est un dictionnaire dont les clés sont un
-triplet ::
-
- <type de relation>, <type d'entité cible>, <position du contexte ("subject" ou "object"
-
-et les valeurs un `set` ou un tuple de marqueurs définissant des propriétés
-s'appliquant à cette relation.
-
-Il est possible de simplifier ce dictionnaire :
-
-* si l'on veut spécifier un seul marqueur, il n'est pas nécessaire d'utiliser
- un tuple comme valeur, le marqueur seul (chaine de caractères) suffit
-* si l'on s'intéresse uniquement à un type de relation et non à la cible et à la
- position du contexte (ou que celui-ci n'est pas ambigüe), on peut simplement
- utiliser le nom du type de relation comme clé
-* si l'on veut qu'un marqueur s'applique quelque soit le type d'entité cible, il
- faut utiliser la chaine `*` comme type d'entité cible
-
-A noter également que ce dictionnaire est *traité à la création de la classe*.
-Il est automatiquement fusionné avec celui de la ou des classe(s) parentes (pas
-besoin de copier celui de la classe parent pour le modifier). De même modifier
-celui-ci après création de la classe n'aura aucun effet...
-
-
-.. include:: sect_definition_entites.txt
--- a/goa/doc/devmanual_fr/chap_migration.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-Migration
-=========
-
-Une des idées de base d'CubicWeb est la création incrémentale d'application, et
-pour cela de nombreuses actions sont fournies afin de facilement faire évoluer
-une application et tout particulièrement le modèle de données manipulé sans
-perdre les données des instances existantes.
-
-La version courante d'un modèle d'application est données dans le fichier
-`__pkginfo__.py` sous forme d'un tuple de 3 entiers.
-
-
-Gestion des scripts de migrations
----------------------------------
-Les scripts des migrations doivent être placés dans le répertoire `migration` de
-l'application, et nommé de la manière suivante :
-
- <n° de version X.Y.Z>[_<description>]_<mode>.py
-
-dans lequel :
-
-* X.Y.Z correspond au n° de version du modèle vers lequel le script permet de
- migrer,
-
-* le *mode* (entre le dernier "_" et l'extension ".py") indique à quelle partie
- de l'application (serveur RQL, serveur web) le script s'applique en cas
- d'installation distribuée. Il peut valoir :
-
- * `common`, s'applique aussi bien sur le serveur RQL que sur le serveur web,
- et met à jour des fichiers sur le disque (migration de fichier de
- configuration par exemple).
-
- * `web`, s'applique uniquement sur le serveur web, et met à jour des fichiers
- sur le disque
-
- * `repository`, s'applique uniquement sur le serveur RQL, et met à jour des
- fichiers sur le disque
-
- * `Any`, s'applique uniquement sur le serveur RQL, et met à jour des
- données en base (migrations de schéma et de données par ex.)
-
-
-Toujours dans le répertoire `migration`, le fichier spécial `depends.map` permet
-d'indiquer que pour migrer vers une version spécifique du modèle, il faut tout
-d'abord avoir migrer vers une version données de cubicweb. Ce fichier peut contenir
-des commentaires (lignes commençant par un "#"), et une dépendance est notée sur
-une ligne de la manière suivante : ::
-
- <n° de version du modèle X.Y.Z> : <n° de version cubicweb X.Y.Z>
-
-Par exemple ::
-
- 0.12.0: 2.26.0
- 0.13.0: 2.27.0
- # 0.14 works with 2.27 <= cubicweb <= 2.28 at least
- 0.15.0: 2.28.0
-
-
-Contexte de base
-----------------
-Les identifiants suivants sont préféfinis dans les scripts de migration :
-
-* `config`, configuration de l'instance
-
-* `interactive_mode`, booléen indiquant si le script est éxécuté en mode
- interactif ou non
-
-* `appltemplversion`, version du modèle d'application de l'instance
-
-* `applcubicwebversion`, version cubicweb de l'instance
-
-* `templversion`, version du modéle d'application installée
-
-* `cubicwebversion`, version cubicweb installée
-
-* `confirm(question)`, fonction posant une question et retournant vrai si
- l'utilisateur a répondu oui, faux sinon (retourne toujours vrai en mode non
- interactif)
-
-* `_`, fonction équivalente à `unicode` permettant de marquer des chaines à
- internationaliser dans les scripts de migration
-
-Dans les scripts "repository", les identifiants suivant sont également définis :
-
-* `checkpoint`, demande confirmant et effectue un "commit" au point d'appel
-
-* `repo_schema`, schéma persistent de l'instance (i.e. schéma de l'instance en
- cours de migration)
-
-* `newschema`, schéma installé sur le système de fichier (i.e. schéma de la
- version à jour du modèle et de cubicweb)
-
-* `sqlcursor`, un curseur SQL pour les très rares cas où il est réellement
- nécessaire ou avantageux de passer par du sql
-
-* `repo`, l'objet repository
-
-
-Migration de schéma
--------------------
-Les fonctions de migration de schéma suivantes sont disponibles dans les scripts
-"repository" :
-
-* `add_attribute(etype, attrname, attrtype=None, commit=True)`, ajoute un
- nouvel attribut à un type d'entité existante. Si le type de celui-ci n'est pas
- spécifié il est extrait du schéma à jour.
-
-* `drop_attribute(etype, attrname, commit=True)`, supprime un
- attribut à un type d'entité existante.
-
-* `rename_attribute(etype, oldname, newname, commit=True)`, renomme un attribut
-
-* `add_entity_type(etype, auto=True, commit=True)`, ajoute un nouveau type
- d'entité. Si `auto` est vrai, toutes les relations utilisant ce type d'entité
- et ayant un type d'entité connu à l'autre extrémité vont également être
- ajoutées.
-
-* `drop_entity_type(etype, commit=True)`, supprime un type d'entité et toutes
- les relations l'utilisant.
-
-* `rename_entity_type(oldname, newname, commit=True)`, renomme un type d'entité
-
-* `add_relation_type(rtype, addrdef=True, commit=True)`, ajoute un nouveau type
- de relation. Si `addrdef` est vrai, toutes les définitions de relation de ce
- type seront également ajoutées.
-
-* `drop_relation_type(rtype, commit=True)`, supprime un type de relation et
- toutes les définitions de ce type.
-
-* `rename_relation(oldname, newname, commit=True)`, renomme une relation.
-
-* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, ajoute une
- définition de relation.
-
-* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, supprime
- une définition de relation.
-
-* `synchronize_permissions(ertype, commit=True)`, synchronise les permissions
- d'un type d'entité ou de relation
-
-* `synchronize_rschema(rtype, commit=True)`, synchronise les propriétés et
- permissions d'un type de relation.
-
-* `synchronize_eschema(etype, commit=True)`, synchronise les propriétés et
- permissions d'un type d'entité.
-
-* `synchronize_schema(commit=True)`, synchronise le schéma persistent avec le
- schéma à jour (mais sans ajouter ni supprimer de nouveaux types d'entités ou
- de relations ni de définitions de relation).
-
-* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, change
- les propriétés d'une definition de relation en utilisant les arguments nommés
- pour les propriétés à changer.
-
-* `set_widget(etype, rtype, widget, commit=True)`, change le widget à utiliser
- pour la relation <rtype> du type d'entité <etype>
-
-* `set_size_constraint(etype, rtype, size, commit=True)`, change la contrainte
- de taille pour la relation <rtype> du type d'entité <etype>
-
-
-Migration de données
---------------------
-Les fonctions de migration de données suivantes sont disponibles dans les scripts
-"repository" :
-
-* `rqlexec(rql, kwargs=None, cachekey=None, ask_confirm=True)`, éxécute une
- requête rql arbitraire, d'interrogation ou de modification. Un objet result
- set est retourné.
-
-* `rqlexecall(rqliter, cachekey=None, ask_confirm=True)`, éxécute une série
- de requêtes rql arbitraires, d'interrogation ou de modification. rqliter est
- un itérateur retournant des couples (rql, kwargs). Le result set de la
- dernière requête éxécutée est retourné.
-
-* `add_entity(etype, *args, **kwargs)`, ajoute une nouvelle entité du type
- données. La valeur des attributs et relations est spécifiée en utilisant les
- arguments nommés et positionnels.
-
-
-Création de workflow
---------------------
-Les fonctions de création de workflow suivantes sont disponibles dans les scripts
-"repository" :
-
-* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, ajoute un
- nouvel état de workflow
-
-* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`,
- ajoute une nouvelle transtion de workflow
-
-Migration de configuration
---------------------------
-Les fonctions de migration de configuration suivantes sont disponibles dans tout
-les scripts :
-
-* `option_renamed(oldname, newname)`, indique qu'une option a été renommée
-
-* `option_group_change(option, oldgroup, newgroup)`, indique qu'une option a
- changé de groupe
-
-* `option_added(oldname, newname)`, indique qu'une option a été ajoutée
-
-* `option_removed(oldname, newname)`, indique qu'une option a été supprimée
-
-
-Autres fonctions de migration
------------------------------
-Ces fonctions ne sont utilisés que pour des opérations de bas niveau
-irréalisables autrement ou pour réparer des bases cassées lors de session
-interactive. Elles sont disponibles dans les scripts "repository".
-
-* `sqlexec(sql, args=None, ask_confirm=True)`, éxécute une requête sql
- arbitraire, à n'utiliser
-
-* `add_entity_type_table(etype, commit=True)`
-* `add_relation_type_table(rtype, commit=True)`
-* `uninline_relation(rtype, commit=True)`
--- a/goa/doc/devmanual_fr/chap_mise_en_place_environnement.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-Mise en place d'un environnement de développement CubicWeb
-=======================================================
-
-.. include:: sect_mercurial.txt
-.. include:: sect_installation.txt
-.. include:: sect_cubicweb-ctl.txt
-
-
-
-Création d'un composant
------------------------
-Commençons par créer un squelette qui nous servira de base au développement de
-notre composant ou application ::
-
- cd ~/hg
- cubicweb-ctl newtemplate moncomposant
- # répondre aux questions
- hg init moncomposant
- cd moncomposant
- hg add .
- hg ci
-
-A partir de là si tout va bien, votre composant devrait être affiché par
-`cubicweb-ctl list` dans la section *Avaible components*, si ce n'est pas le cas
-revoir la section `Configuration de l'environnement`_.
-
-
-Création d'une instance de développement
-----------------------------------------
-
-Maintenant que nous avons notre squelette de modèle, on peut en créer une
-instance afin de voir ce que tout ça donne dans un simple navigateur web.
-Nous allons utiliser une configuration `all-in-one` afin de simplifier les
-choses ::
-
- cubicweb-ctl create all-in-one moncomposant moninstance
-
-Une série de questions vont être posées, la réponse par défaut est généralement
-suffisante. Vous pourrez de toute façon modifier la configuration par la suite
-en éditant les fichiers générés. Lorsqu'un login/mot de passe d'accès au sgbd
-vous est demandé, il est recommandé d'utilisé l'utilisateur créé lors de la
-`Configuration Postgres`_.
-
-Il est important de distinguer ici l'utilisateur utilisé pour accéder au sgbd,
-et l'utilisateur utilisé pour s'authentifier dans l'application cubicweb. Lorsque
-l'application cubicweb démarre, elle utilise le login/mot de passe sgdb pour
-récupérer le schéma et gérer les transactions bas-niveau. En revanche, lorsque
-`cubicweb-ctl create` vous demande un login/mot de passe `manager` pour cubicweb, il
-s'agit d'un utilisateur qui sera créé dans l'application `cubicweb` pour pouvoir
-s'y connecter dans un premier temps et l'administrer. Il sera par la suite possible
-de créer des utilisateurs différents pour l'application.
-
-A l'issue de cette commande, la définition de votre instance se trouve dans
-*~/etc/cubicweb.d/moninstance/*. Pour la lancer, il suffit de taper ::
-
- cubicweb-ctl start -D moninstance
-
-L'option `-D` indique le *debug mode* : l'instance ne passe pas en mode serveur
-et ne se déconnecte pas du terminal, ce qui simplifie le dépannage en cas de non
-démarrage de l'instance. Vous pouvez ensuite allez voir ce que ça donne en
-pointant votre navigateur sur l'url `http://localhost:8080` (le n° de port
-dépend de votre configuration). Pour vous authentifier vous pouvez utiliser le
-login/mot de passe administrateur que vous avez spécifié lors de la création de
-l'instance.
-
-Pour arrêter l'instance, un Ctrl-C dans la fenêtre où vous l'avez lancé
-suffit. Si l'option `-D` a été omise, il faut taper ::
-
- cubicweb-ctl stop moninstance
-
-Voilà, tout est en place pour démarrer le développement du modèle...
-
-
-Utilisation de cubicweb-liveserver
--------------------------------
-
-Afin de tester rapidement un nouveau composant, on peut également
-utiliser le script `cubicweb-liveserver` qui permet de créer une
-application en mémoire (utilisant une base de données SQLite par
-défaut) et la rendre accessible via un serveur web::
-
- cubicweb-liveserver moncomposant
-
-ou bien, pour utiliser une base de données existante (SQLite ou postgres)::
-
- cubicweb-liveserver -s monfichier_sources moncomposant
-
--- a/goa/doc/devmanual_fr/chap_rql.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-Le langage RQL (Relation Query Language)
-========================================
-
-Présentation
-------------
-* langage mettant l'accent sur le parcours de relations.
-* Les attributs sont considérés comme des cas particuliers de relations.
-* RQL s'inspire de SQL mais se veut plus haut niveau.
-* Une connaissance du schéma CubicWeb définissant l'application est nécessaire.
-
-
-Les différents types de requêtes
---------------------------------
-Recherche (`Any`)
- interroger l'entrepôt afin d'extraire des entités et/ou des attributs
- d'entités.
-
-Insertion (`INSERT`)
- insérer de nouvelles entités dans la base.
-
-Mise à jour d'entités, création de relations (`SET`)
- mettre à jours des entités existantes dans la base, ou de créer des
- relations entres des entités existantes.
-
-Suppression d'entités ou de relation (`DELETE`)
- supprimer des entités et relations existantes dans la base.
-
-
-Variables et typage
--------------------
-Les entités et valeurs à parcourir et / ou séléctionner sont représentées dans
-la requête par des *variables* qui doivent être écrites en majuscule.
-
-Les types possibles pour chaque variable sont déduits à partir du schéma en
-fonction des contraintes présentes dans la requête.
-
-On peut contraindre les types possibles pour une variable à l'aide de la
-relation spéciale `is`.
-
-Types de bases
---------------
-* `String` (litéral: entre doubles ou simples quotes).
-* `Int`, `Float` (le séparateur étant le '.').
-* `Date`, `Datetime`, `Time` (litéral: chaîne YYYY/MM/DD[ hh:mm] ou mots-clés
- `TODAY` et `NOW`).
-* `Boolean` (mots-clés `TRUE` et `FALSE`).
-* mot-clé `NULL`.
-
-Opérateurs
-----------
-* Opérateurs logiques : `AND`, `OR`, `,`.
-* Opérateurs mathématiques: `+`, `-`, `*`, `/`.
-* Operateur de comparaisons: `=`, `<`, `<=`, `>=`, `>`, `~=`, `LIKE`, `IN`.
-
- * L'opérateur `=` est l'opérateur par défaut.
-
- * L'opérateur `LIKE` / `~=` permet d'utiliser le caractère `%` dans une chaine
- de caractère pour indiquer que la chaîne doit commencer ou terminer par un
- préfix/suffixe::
-
- Any X WHERE X nom ~= 'Th%'
- Any X WHERE X nom LIKE '%lt'
-
- * L'opérateur `IN` permet de donner une liste de valeurs possibles::
-
- Any X WHERE X nom IN ('chauvat', 'fayolle', 'di mascio', 'thenault')
-
-Requête de recherche
---------------------
-
- [`DISTINCT`] <type d'entité> V1(, V2)\*
- [`GROUPBY` V1(, V2)\*] [`ORDERBY` <orderterms>]
- [`WHERE` <restriction>]
- [`LIMIT` <value>] [`OFFSET` <value>]
-
-:type d'entité:
- Type de la ou des variables séléctionnées.
- Le type spécial `Any`, revient à ne pas spécifier de type.
-:restriction:
- liste des relations à parcourir sous la forme
- `V1 relation V2|<valeur constante>`
-:orderterms:
- Définition de l'ordre de selection : variable ou n° de colonne suivie de la
- méthode de tri (`ASC`, `DESC`), ASC étant la valeur par défaut.
-:note pour les requêtes groupées:
- Pour les requêtes groupées (i.e. avec une clause `GROUPBY`), toutes les
- variables sélectionnée doivent être soit groupée soit aggrégée.
-
-Exemples - recherche
-`````````````````````
-::
-
- Any X WHERE X eid 53
- Personne X
- Personne X WHERE X travaille_pour S, S nom "logilab"
- Any E,COUNT(X) GROUPBY E ORDERBY EN WHERE X is E, E name EN
- Any E,COUNT(X) GROUPBY E ORDERBY 2 WHERE X is E
-
-
-Fonctionnalités avancées
-````````````````````````
-* Fonctions d'aggrégat : `COUNT`, `MIN`, `MAX`, `SUM`.
-* Fonctions sur les chaines :`UPPER`, `LOWER`.
-* Relations optionnelles :
-
- * Elles permettent de sélectionner des entités liées ou non à une autre.
-
- * Il faut utiliser le `?` derrière la variable pour spécifier que la relation
- vers celle-ci est optionnelle :
-
- - Anomalies d'un projet attachées ou non à une version ::
-
- Any X,V WHERE X concerns P, P eid 42, X corrected_in V?
-
- - Toutes les fiches et le projet qu'elles documentent le cas échéant ::
-
- Any C,P WHERE C is Card, P? documented_by C
-
-Négation
-````````
-* Une requête du type `Document X WHERE NOT X owned_by U` revient à dire "les
- documents n'ayant pas de relation `owned_by`".
-* En revanche la requête `Document X WHERE NOT X owned_by U, U login "syt"`
- revient à dire "les documents n'ayant pas de relation `owned_by` avec
- l'utilisateur syt". Ils peuvent avoir une relation "owned_by" avec un autre
- utilisateur.
-
-
-Requête d'insertion
--------------------
- `INSERT` <type d'entité> V1(, <type d'entité> V2)\* `:` <assignements>
- [`WHERE` <restriction>]
-
-:assignements:
- liste des relations à assigner sous la forme `V1 relation V2|<valeur constante>`
-
-La restriction permet de définir des variables utilisées dans les assignements.
-
-Attention, si une restriction est spécifiée, l'insertion est effectuée *pour
-chaque ligne de résultat renvoyée par la restriction*.
-
-Exemples - insertion
-`````````````````````
-* Insertion d'une nouvelle personne nommée 'bidule'::
-
- INSERT Personne X: X nom 'bidule'
-
-* Insertion d'une nouvelle personne nommée 'bidule', d'une autre nommée
- 'chouette' et d'une relation 'ami' entre eux::
-
- INSERT Personne X, Personne Y: X nom 'bidule', Y nom 'chouette', X ami Y
-
-* Insertion d'une nouvelle personne nommée 'bidule' et d'une relation 'ami' avec
- une personne existante nommée 'chouette'::
-
- INSERT Personne X: X nom 'bidule', X ami Y WHERE Y nom 'chouette'
-
-
-Requête de mise à jour
-----------------------
- `SET` <assignements>
- [`WHERE` <restriction>]
-
-Attention, si une restriction est spécifiée, la mise à jour est effectuée *pour
-chaque ligne de résultat renvoyée par la restriction*.
-
-Exemples - mise à jour
-````````````````````````
-* Renommage de la personne nommée 'bidule' en 'toto', avec modification du
- prénom::
-
- SET X nom 'toto', X prenom 'original' WHERE X is 'Person', X nom 'bidule'
-
-* Insertion d'une relation de type 'connait' entre les objets reliés par la
- relation de type 'ami'::
-
- SET X know Y WHERE X ami Y
-
-Requête de suppression
-----------------------
- `DELETE` (<type d''entité> V) | (V1 relation v2),...
- [`WHERE` <restriction>]
-
-Attention, si une restriction est spécifiée, la suppression est effectuée *pour
-chaque ligne de résultat renvoyée par la restriction*.
-
-Exemples
-````````
-* Suppression de la personne nommé 'toto'::
-
- DELETE Person X WHERE X nom 'toto'
-
-* Suppression de toutes les relations de type 'ami' partant de la personne
- nommée 'toto'::
-
- DELETE X ami Y WHERE X is 'Person', X nom 'toto'
--- a/goa/doc/devmanual_fr/chap_serveur_crochets.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-Les crochets (*hooks*)
-======================
-
-XXX FILLME
--- a/goa/doc/devmanual_fr/chap_serveur_notification.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-Gestion de notifications
-========================
-
-XXX FILLME
\ No newline at end of file
--- a/goa/doc/devmanual_fr/chap_tests.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-Tests
-=====
-
-Écriture de tests unitaires
----------------------------
-Le framework de test fournit principalement deux classes de tests dans le module
-`cubicweb.devtools.apptest`:
-
-* `EnvBasedTC`, pour simuler un environnement complet (web + repository)
-* `RepositoryBasedTC`, pour simuler un environnement de repository uniquement
-
-Ces deux classes ont quasiment la même interface et proposent un certain nombre de méthodes
-rendant l'écriture de test puissante et rapide.
-
-XXXFILLME describe API
-
-Dans la plupart des cas, vous allez vouloir hériter de `EnvBasedTC` pour écrire des tests
-unitaires ou fonctionnels pour vos entités, vues, crochets...
-
-
-Test des courriels de notifications
-```````````````````````````````````
-Lors de l'éxécution de tests les courriels potentiellement générés ne sont pas réellement
-envoyé mais se retrouve dans la liste `MAILBOX` du module `cubicweb.devtools.apptest`. Cette
-liste est remise à zéro au *setUp* de chaque test (par le setUp des classes `EnvBasedTC`
-et `RepositoryBasedTC`).
-
-Vous pouvez donc tester vos notifications en analysant le contenu de cette liste, qui
-contient des objets ayant deux attributs :
-* `recipients`, la liste des destinataires
-* `msg`, l'objet email.Message
-
-
-Tests automatiques
-------------------
-XXXFILLME
--- a/goa/doc/devmanual_fr/chap_ui_gestion_formulaire.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-Gestion de formulaires
-======================
-
-Contrôle de la génération automatique de formulaire pour les entités manipulée
-------------------------------------------------------------------------------
-XXX FILLME
-
-* les formulaires 'edition' et 'creation'
-
-Le formulaire généré par défaut ne vous convient pas ? Vous êtes peut-être pas
-obligé de le refaire à la main ! :)
-
-* rtags primary, secondary, generated, generic,
- `Entity.relation_category(rtype, x='subject')`
-* inline_view (now a rtag?)
-* spécification widget
-
-
-Fonctionnement du contrôleur d'édition par défaut (id: 'edit')
---------------------------------------------------------------
-
-Contrôle de l'édition
-`````````````````````
-Prérequis: les paramètres liés aux entités à éditer sont spécifiés de la forme ::
-
- <nom de champ>:<eid de l'entité>
-
-où l'eid de l'entité pourra être une lettre dans le cas d'une entité à créer. On
-dénommera ces paramètres comme *qualifié*.
-
-1. récupération des entités à éditer en cherchant les paramètres de formulaire
- commençant par 'eid:' ayant également un paramètre '__type' associé
- (également *qualifié* par l'eid évidemment)
-
-2. pour tous les attributs et relations de chaque entité à éditer
-
- 1. recherche d'un paramètre 'edits-<nom relation>' ou 'edito-<nom relation>'
- qualifié dans le cas d'une relation dont l'entité est objet
- 2. si trouvé, la valeur récupérée est considérée comme la valeur originale
- pour cette relation, et on cherche la (ou les) nouvelle(s) valeur(s) dans
- le paramètre <nom relation> (qualifié)
- 3. si la valeur est différente de l'originale, une requête de modification en
- base est effectuée
-
-3. pour chaque entité à éditer
-
- 1. si un paramètre `__linkto` qualifié est spécifié, sa valeur doit être une
- chaine (ou une liste de chaine) de la forme : ::
-
- <relation type>:<eids>:<target>
-
- où <target> vaut 'subject' ou 'object' et chaque eid peut-être séparé d'un
- autre par un '_'. Target spécifie *l'entité éditée* est sujet ou objet de la
- relation et chaque relation ainsi spécifiée sera insérée.
-
- 2. si un paramètre `__cloned_eid` qualifié est spécifié pour une entité, les
- relations de l'entité spécifiée en valeur de cette argument sont copiées sur
- l'entité éditée
-
-
- 3. si un paramètre `__delete` qualifié est spécifié, sa valeur doit être une
- chaine (ou une liste de chaine) de la forme : ::
-
- <subject eids>:<relation type>:<object eids>
-
- où chaque eid sujet ou objet peut-être séparé d'un autre par un '_'. Chaque
- relation ainsi spécifiée sera supprimée.
-
- 4. si un paramètre `__insert` qualifié est spécifié, sa valeur doit être de
- même format que pour `__delete`, mais chaque relation ainsi spécifiée sera
- insérée.
-
-4. si les paramètres `__insert` et/ou `__delete` sont trouvés non qualifiés,
- ils sont interprétés comme décrit ci-dessus (quelque soit le nombre d'entité
- édité)
-
-5. si aucune entité n'est éditée mais que le formulaire contient les paramètres
- `__linkto` et `eid`, celui-ci est interprété en prenant la valeur spécifié
- par le paramètre `eid` pour désigner l'entité sur laquelle ajouter les
- relations
-
-
-A noter que :
-
-* si le paramètre `__action_delete` est trouvé, toutes les entités comme
- spécifiées à éditer seront supprimées
-
-* si le paramètre `__action_cancel` est trouvé, aucune action n'est effectuée
-
-* si le paramètre `__action_apply` est trouvé, l'édition est effectuée
- normalement mais la redirection sera effectuée sur le formulaire (cf `Contrôle
- de la redirection`_)
-
-* le paramètre `__method` est également supporté comme sur le template principal
- (XXX not very consistent, maybe __method should be dealed in the view controller)
-
-* si aucune entité à éditer n'est trouvée et qu'il n'y a pas de paramètre
- `__action_delete`, `__action_cancel`, `__linkto`, `__delete` ou `__insert`,
- une erreur est levée
-
-* placer dans le formulaire le paramètre `__message` permettra d'utiliser la
- valeur de ce paramètre comme message d'information à l'utilisateur une fois
- l'édition effectuée.
-
-
-Contrôle de la redirection
-``````````````````````````
-Une fois que l'édition s'est bien passé, reste un problème : c'est bien beau
-tout ça, mais où qu'on va maintenant ?? Si rien n'est spécifié, le controlleur
-se débrouille, mais comme il fait pas toujours ce qu'on voudrait, on peut
-controller ça en utilisant les paramètres suivant :
-
-* `__redirectpath`: chemin de l'url (relatif à la racine du site, sans paramètre
- de formulaire
-
-* `__redirectparams`: paramètres de formulaires à ajouter au chemin
-
-* `__redirectrql`: requête RQL de redirection
-
-* `__redirectvid`: identifiant de vue de redirection
-
-* `__errorurl`: url du formulaire original, utilisé pour la redirection en cas
- d'erreur de validation pendant l'édition. Si celui-ci n'est pas spécifié, une
- page d'erreur sera présentée plutot qu'un retour sur le formulaire (qui est le
- cas échéant responsable d'afficher les erreurs)
-
-* `__form_id`: identifiant de vue du formulaire original, utilisée si
- `__action_apply` est trouvé
-
-En général on utilise soit `__redirectpath et `__redirectparams` soit
-`__redirectrql` et `__redirectvid`.
--- a/goa/doc/devmanual_fr/chap_ui_js_json.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-AJAX
-====
-JSON bla bla
-XXX FILLME
-
-
-Le contrôleur 'json'
---------------------
-XXX FILLME
-
-
-API Javascript
---------------
-XXX FILLME
--- a/goa/doc/devmanual_fr/chap_visualisation_donnees.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-Définition de vues
-==================
-
-Les classes de base des vues
-----------------------------
-
-La class `View` (`cubicweb.common.view`)
-`````````````````````````````````````
-Un vue écrit dans son flux de sortie via son attribut `w` (`UStreamIO`).
-
-L'interface de base des vues est la suivante :
-
-* `dispatch(**context)`, appelle ("rend") la vue en appellent `call` ou
- `cell_call` en fonction des arguments passé
-* `call(**kwargs)`, appelle la vue pour un result set complet ou nul
-* `cell_call(row, col, **kwargs)`, appelle la vue pour une cellule donnée d'un
- result set
-* `url()`, retourne l'url permettant d'obtenir cette vue avec le result set en
- cours
-* `view(__vid, rset, __fallback_vid=None, **kwargs)`, appelle la vue
- d'identificant `__vid` sur le result set donné. Il est possible de données un
- identificant de vue de "fallback" qui sera utilisé si la vue demandée n'est
- pas applicable au result set
-
-* `wview(__vid, rset, __fallback_vid=None, **kwargs)`, pareil que `view` mais
- passe automatiquement le flux en argument
-
-* `html_headers()`, retourne une liste d'en-tête HTML à placer par le template
- principal
-
-* `page_title()`, retourne le titre à utiliser dans l'en tête HTML `title`
-
-* `creator(eid)`, retourne l'eid et le login du créateur de l'entité ayant
- l'eid passé en argument
-
-Autres classes de base :
-
-* `EntityView`, vue s'appliquant à aux lignes ou cellule contenant une entité
- (eg un eid)
-* `StartupView`, vue de départ n'ayant pas besoin de result set
-* `AnyRsetView`, vue s'appliquant à n'importe quelle result set
-
-
-Les templates ou patron
------------------------
-
-Les patrons (ou *template*) sont des cas particulier de vue ne dépendant a
-priori pas d'un result set. La classe de base `Template` (`cubicweb.common.view`)
-est une classe dérivée de la classe `View`.
-
-Pour construire une page HTML, un *template principal* est utilisé. Généralement
-celui possédant l'identifiant 'main' est utilisé (ce n'est pas le cas lors
-d'erreur dans celui-ci ou pour le formulaire de login par exemple). Ce patron
-utilise d'autres patrons en plus des vues dépendants du contenu pour générer la
-page à renvoyer.
-
-C'est ce template qui est chargé :
-
-1. d'éxécuter la requête RQL des données à afficher le cas échéant
-2. éventuellement de déterminer la vue à utiliser pour l'afficher si non
- spécifiée
-3. de composer la page à retourner
-
-
-Le patron principal par défaut (`cubicweb.web.views.basetemplates.TheMainTemplate`)
---------------------------------------------------------------------------------
-
-Le template principal par défaut construit la page selon la décomposition
-suivante :
-
-.. image:: main_template_layout.png
-
-Le rectancle contenant le `view.dispatch()` représente l'emplacement où est
-inséré la vue de contenu à afficher. Les autres représentent des sous-templates
-appelé pour construire la page. Les implémentations par défaut de tout ces
-templates sont dans le module `cubicweb.web.views.basetemplates`. Vous pouvez
-évidemment surcharger l'un des sous-templates pour modifier l'aspect visuel
-d'une partie désirée de la page.
-
-On peut également contrôler certains comportements du template principal à
-l'aide des paramètres de formulaire suivante :
-
-* `__notemplate`, si présente (quelque soit la valeur associée), seule la vue de
- contenu est renvoyée
-* `__force_display`, si présente et contient une valeur non nulle, pas de
- navigation quelque soit le nombre d'entités à afficher
-* `__method`, si le result set à afficher ne contient qu'une entité et que ce
- paramètre est spécifié, celui-ci désigne une méthode à appeler sur l'entité
- en lui donnant en argument le dictionnaire des paramètres de formulaire, avant
- de reprendre le comportement classique (s'insère entre les étapes 1. et
- 2. décrites ci-dessus)
-
-
-.. include:: sect_stdlib_vues.txt
-
-
-Vues xml, binaires...
----------------------
-Pour les vues générants autre que du html (une image générée dynamiquement par
-exemple), et qui ne peuvent donc généralement pas être incluse dans la page
-HTML générée par le template principal (voir ci-dessus), il faut :
-
-* placer l'attribut `templatable` de la classe à `False`
-* indiquer via l'attribut `content_type` de la classe le type MIME généré par la
- vue 'application/octet-stream'
-
-Pour les vues générants un contenu binaire (une image générée dynamiquement par
-exemple), il faut également placer l'attribut `binary` de la classe à `True` (ce
-qui implique `templatable == False` afin que l'attribut `w` de la vue soit
-remplacé par un flux binaire plutôt que unicode.
-
-
-Quelques trucs (X)HTML à respecter
-----------------------------------
-Certains navigateurs (dont firefox) n'aime pas les `<div>` vides (par vide
-j'entend sans contenu dans la balise, il peut y avoir des attributs), faut
-toujours mettre `<div></div>` même s'il n'y a rien dedans, et non `<div/>`.
--- a/goa/doc/devmanual_fr/index.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-=======================================
-Développement d'applications avec CubicWeb
-=======================================
-
-
-:Author: Logilab
-:Organization: Logilab
-
-.. contents::
-
-.. include:: chap_fondements_cubicweb.txt
-.. include:: chap_mise_en_place_environnement.txt
-.. include:: chap_rql.txt
-.. include:: chap_definition_schema.txt
-.. include:: chap_definition_workflows.txt
-.. include:: chap_bases_framework_cubicweb.txt
-.. include:: chap_visualisation_donnees.txt
-.. include:: chap_manipulation_donnees.txt
-.. include:: chap_ui_gestion_formulaire.txt
-.. include:: chap_ui_js_json.txt
-.. include:: chap_autres_composants_ui.txt
-.. include:: chap_serveur_crochets.txt
-.. include:: chap_serveur_notification.txt
-
-.. include:: chap_tests.txt
-.. include:: chap_i18n.txt
-.. include:: chap_migration.txt
-
-.. include:: chap_configuration_instance.txt
-
-XXX: XXX FILLME, CSS, API sécurité
Binary file goa/doc/devmanual_fr/main_template_layout.dia has changed
Binary file goa/doc/devmanual_fr/main_template_layout.png has changed
--- a/goa/doc/devmanual_fr/makefile Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-MKHTMLOPTS=--doctype book --param toc.section.depth=1 --target html --stylesheet single-file
-SRC=.
-
-MKPDFOPTS=--doctype book --param toc.section.depth=2 --target pdf --stylesheet standard
-
-TXTFILES:= $(wildcard *.txt)
-TARGET := $(TXTFILES:.txt=.html)
-
-all: index.html
-
-index.html: *.txt
- mkdoc ${MKHTMLOPTS} index.txt
-
-index.pdf: *.txt
- mkdoc ${MKPDFOPTS} index.txt
-
-%.html: %.txt
- mkdoc ${MKHTMLOPTS} $<
-
-clean:
- rm -f *.html
--- a/goa/doc/devmanual_fr/sect_definition_entites.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-Paramétrages et extensions spécifiques
---------------------------------------
-
-Valeurs par défaut dynamiques
-`````````````````````````````
-Il est possible de définir dans le schéma des valeurs par défaut *statiques*.
-Il est également possible de définir des valeurs par défaut *dynamiques* en
-définissant sur la classe d'entité une méthode `default_<nom attribut>` pour
-un attribut donnée.
-
-
-Contrôle des attributs chargés et du tri par défaut
-```````````````````````````````````````````````````
-* l'attribut de classe `fetch_attrs` permet de définir sur une classe d'entité
- la liste des noms des attributs ou relations devant être chargés
- automatiquement lors de la récupération d'entité(s) de ce type. Dans le cas
- des relations, on est limité aux relations *sujets de cardinalité `?` ou `1`*.
-
-* la méthode de classe `fetch_order(attr, var)` prend en argument un nom
- d'attribut (ou de relation) et un nom de variable et doit retourner une chaine
- à utiliser dans la close "ORDERBY" d'une requête RQL pour trier
- automatiquement les listes d'entités de ce type selon cet attribut, ou `None`
- si l'on ne veut pas de tri sur l'attribut passé en argument. Par défaut les
- entités sont triées selon leur date de création
-
-* la méthode de classe `fetch_unrelated_order(attr, var)` est similaire à la
- méthode `fetch_order` mais est utilisée essentiellement pour contrôler le tri
- des listes déroulantes permettant de créer des relations dans la vue d'édition
- d'une entité
-
-La fonction `fetch_config(fetchattrs, mainattr=None)` permet de simplifier la
-définition des attributs à précharger et du tri en retournant une liste des
-attributs à précharger (en considérant ceux de la classe `AnyEntity`
-automatiquement) et une fonction de tri sur l'attribut "principal" (le 2eme
-argument si spécifié ou sinon le premier attribut de la liste `fetchattrs`).
-Cette fonction est définie dans le package `cubicweb.entities`.
-
-Par exemple : ::
-
- class Transition(AnyEntity):
- """..."""
- id = 'Transition'
- fetch_attrs, fetch_order = fetch_config(['name'])
-
-Indique que pour le type d'entité "Transition" il faut précharger l'attribut
-"name" et trier par défaut selon cet attribut.
-
-
-Contrôle des formulaires d'édition
-``````````````````````````````````
-Il est possible de contrôler les attributs/relations dans la vue d'édition
-simple ou multiple à l'aide des *rtags* suivants :
-
-* `primary`, indique qu'un attribut ou une relation doit être incorporé dans
- les formulaires d'édition simple et multiple. Dans le cas d'une relation,
- le formulaire d'édition de l'entité liée sera inclus dans le formulaire
-
-* `secondary`, indique qu'un attribut ou une relation doit être incorporé dans
- le formulaire d'édition simple uniquement. Dans le cas d'une relation,
- le formulaire d'édition de l'entité liée sera inclus dans le formulaire
-
-* `generic`, indique qu'une relation doit être incorporé dans le formulaire
- d'édition simple dans la boite générique d'ajout de relation
-
-* `generated`, indique qu'un attribut est caculé dynamiquement ou autre, et
- qu'il ne doit donc pas être présent dans les formulaires d'édition
-
-Au besoin il est possible de surcharger la méthode
-`relation_category(rtype, x='subject')` pour calculer dynamiquement la catégorie
-d'édition d'une relation.
-
-
-Contrôle de la boîte "add_related"
-``````````````````````````````````
-La boite `add related` est une boite automatique proposant de créer une entité
-qui sera automatiquement liée à l'entité de départ (le contexte dans lequel
-s'affiche la boite). Par défaut, les liens présents dans cette boite sont
-calculés en fonction des propriétés du schéma de l'entité visualisée, mais il
-est possible de les spécifier explicitement à l'aide des *rtags* suivants :
-
-* `link`, indique qu'une relation est généralement créée vers une entité
- existante et qu'il ne faut donc pas faire apparaitre de lien pour cette
- relation
-
-* `create`, indique qu'une relation est généralement créée vers de nouvelles
- entités et qu'il faut donc faire apparaitre un lien pour créer une nouvelle
- entité et la lier automatiquement
-
-Au besoin il est possible de surcharger la méthode
-`relation_mode(rtype, targettype, x='subject')` pour caculer dynamiquement la
-catégorie de création d'une relation.
-
-A noter également que si au moins une action dans la catégorie "addrelated" est
-trouvée pour le contexte courant, le fonctionnement automatique est désactivé
-en faveur du fonctionnement explicite (i.e. affichage des actions de la
-catégorie "addrelated" uniquement).
-
-Contrôle des formulaires de filtrage de table
-`````````````````````````````````````````````
-La vue "table" par défaut gère dynamiquement un formulaire de filtrage du
-contenu de celle-ci. L'algorithme est le suivant :
-
-1. on considère que la première colonne contient les entités à restreindre
-2. on recupère la première entité de la table (ligne 0) pour "représenter"
- toutes les autres
-3. pour toutes les autres variables définies dans la requête originale :
-
- 1. si la variable est liée à la variable principale par au moins une
- n'importe quelle relation
- 2. on appelle la méthode `filterform_vocabulary(rtype, x)` sur l'entité
- et si rien est retourné (ou plus exactement un tuple de valeur `None`,
- voir ci-dessous) on passe à la variable suivante, sinon un élément de
- formulaire de filtrage sera créé avec les valeurs de vocabulaire
- retournées
-
-4. il n'y a pas d'autres limitations sur le rql, il peut comporter des clauses
- de tris, de groupes... Des fonctions javascripts sont utilisées pour
- regénérer une requête à partir de la requête de départ et des valeurs
- séléctionnées dans les filtres de formulaire.
-
-
-La méthode `filterform_vocabulary(rtype, x, var, rqlst, args, cachekey)` prend
-en argument le nom d'une relation et la "cible", qui indique si l'entité sur
-laquelle la méthode est appellée est sujet ou objet de la relation. Elle doit
-retourner :
-
-* un 2-uple de None si elle ne sait pas gérer cette relation
-
-* un type et une liste contenant le vocabulaire
-
- * la liste doit contenir des couples (valeur, label)
- * le type indique si la valeur désigne un nombre entier (`type == 'int'`), une
- chaîne de caractères (`type == 'string'`) ou une entité non finale (`type
- == 'eid'`)
-
-Par exemple dans notre application de gestion de tickets, on veut pouvoir
-filtrés ceux-ci par :
-
-* type
-* priorité
-* état (in_state)
-* étiquette (tags)
-* version (done_in)
-
-On définit donc la méthode suivante : ::
-
-
- class Ticket(AnyEntity):
-
- ...
-
- def filterform_vocabulary(self, rtype, x, var, rqlst, args, cachekey):
- _ = self.req._
- if rtype == 'type':
- return 'string', [(x, _(x)) for x in ('bug', 'story')]
- if rtype == 'priority':
- return 'string', [(x, _(x)) for x in ('minor', 'normal', 'important')]
- if rtype == 'done_in':
- rql = insert_attr_select_relation(rqlst, var, rtype, 'num')
- return 'eid', self.req.execute(rql, args, cachekey)
- return super(Ticket, self).filterform_vocabulary(rtype, x, var, rqlst,
- args, cachekey)
-
-
-NOTE: Le support du filtrage sur les étiquettes et l'état est installé
-automatiquement, pas besoin de le gérer ici.
--- a/goa/doc/devmanual_fr/sect_definition_schema.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,339 +0,0 @@
-
-Définition d'un type d'entité
------------------------------
-
-Un type d'entité est définit par une classe python héritant de `EntityType`. Le
-nom de la classe correspond au nom du type. Ensuite le corps de la classe
-contient la description des attributs et des relations pour ce type d'entité,
-par exemple ::
-
- class Personne(EntityType):
- """une personne avec les propriétés et relations nécessaires à mon
- application"""
-
- nom = String(required=True, fulltextindexed=True)
- prenom = String(required=True, fulltextindexed=True)
- civilite = String(vocabulary=('M', 'Mme', 'Mlle'))
- date_naiss = Date()
- travaille_pour = SubjectRelation('Company', cardinality='?*')
-
-* le nom de l'attribut python correspond au nom de l'attribut ou de la relation
- dans cubicweb.
-
-* tout les types de bases sont disponibles nativement : `String`, `Int`, `Float`,
- `Boolean`, `Date`, `Datetime`, `Time`, `Byte`.
-
-* Chaque type d'entité a au moins les méta-relations suivantes :
- - `eid` (`Int`)
- - `creation_date` (`Datetime`)
- - `modification_date` (`Datetime`)
- - `owned_by` (`CWUser`)
- - `is` (`CWEType`)
-
-* il est également possible de définir des relations dont le type d'entité est
- l'objet en utilisant `ObjectRelation` plutôt que `SubjectRelation`
-
-* le premier argument de `SubjectRelation` et `ObjectRelation` donne
- respectivement le type d'entité objet /sujet de la relation. Cela
- peut être :
-
- * une chaine de caractères correspondant à un type d'entité
-
- * un tuple de chaines de caractères correspondant à plusieurs types d'entité
-
- * les chaînes de caractères spéciales suivantes :
-
- - "**" : tout les types d'entité
- - "*" : tout les types d'entité non méta
- - "@" : tout les types d'entité méta mais non "système" (i.e. servant à la
- description du schema en base)
-
-* il est possible d'utiliser l'attribut possible `meta` pour marquer un type
- d'entité comme étant "méta" (i.e. servant à décrire / classifier d'autre
- entités)
-
-* propriétés optionnelles des attributs et relations :
-
- - `description` : chaine de caractères décrivant un attribut ou une
- relation. Par défaut cette chaine sera utilisée dans le formulaire de saisie
- de l'entité, elle est donc destinée à aider l'utilisateur final et doit être
- marquée par la fonction `_` pour être correctement internationalisée.
-
- - `constraints` : liste de contraintes devant être respecté par la relation
- (c.f. `Contraintes`_)
-
- - `cardinality` : chaine de 2 caractères spécifiant la cardinalité de la
- relation. Le premier caractère donne la cardinalité de la relation sur le
- sujet, le 2eme sur l'objet. Quand une relation possède plusieurs sujets ou
- objets possibles, la cardinalité s'applique sur l'ensemble et non un à un (et
- doit donc à priori être cohérente...). Les valeurs possibles sont inspirées
- des expressions régulières :
-
- * `1`: 1..1
- * `?`: 0..1
- * `+`: 1..n
- * `*`: 0..n
-
- - `meta` : booléen indiquant que la relation est une méta relation (faux par
- défaut)
-
-* propriétés optionnelles des attributs :
-
- - `required` : booléen indiquant si l'attribut est obligatoire (faux par
- défaut)
-
- - `unique` : booléen indiquant si la valeur de l'attribut doit être unique
- parmi toutes les entités de ce type (faux par défaut)
-
- - `indexed` : booléen indiquant si un index doit être créé dans la base de
- données sur cette attribut (faux par défaut). C'est utile uniquement si vous
- savez que vous allez faire de nombreuses recherche sur la valeur de cet
- attribut.
-
- - `default` : valeur par défaut de l'attribut. A noter que dans le cas des
- types date, les chaines de caractères correspondant aux mots-clés RQL
- `TODAY` et `NOW` sont utilisables.
-
- - `vocabulary` : spécifie statiquement les valeurs possibles d'un attribut
-
-* propriétés optionnelles des attributs de type `String` :
-
- - `fulltextindexed` : booléen indiquant si l'attribut participe à l'index plein
- texte (faux par défaut) (*valable également sur le type `Byte`*)
-
- - `internationalizable` : booléen indiquant si la valeur de cet attribut est
- internationalisable (faux par défaut)
-
- - `maxsize` : entier donnant la taille maximum de la chaine (pas de limite par
- défaut)
-
-* propriétés optionnelles des relations :
-
- - `composite` : chaîne indiquant que le sujet (composite == 'subject') est
- composé de ou des objets de la relation. Pour le cas opposé (l'objet est
- composé de ou des sujets de la relation, il suffit de mettre 'object' comme
- valeur. La composition implique que quand la relation est supprimé (et donc
- aussi quand le composite est supprimé), le ou les composés le sont
- également.
-
-
-Contraintes
-```````````
-Par défaut les types de contraintes suivant sont disponibles :
-
-* `SizeConstraint` : permet de spécifier une taille minimale et/ou maximale sur
- les chaines de caractères (cas générique de `maxsize`)
-
-* `BoundConstraint` : permet de spécifier une valeur minimale et/ou maximale sur
- les types numériques
-
-* `UniqueConstraint` : identique à "unique=True"
-
-* `StaticVocabularyConstraint` : identique à "vocabulary=(...)"
-
-* `RQLConstraint` : permet de spécifier une requête RQL devant être satisfaite
- par le sujet et/ou l'objet de la relation. Dans cette requête les variables `S`
- et `O` sont préféfinies respectivement comme l'entité sujet et objet de la
- relation
-
-* `RQLVocabularyConstraint` : similaire à la précédente, mais exprimant une
- contrainte "faible", i.e. servant uniquement à limiter les valeurs apparaissant
- dans la liste déroulantes du formulaire d'édition, mais n'empêchant pas une
- autre entité d'être séléctionnée
-
-
-Définition d'un type de relation
---------------------------------
-
-Un type de relation est définit par une classe python héritant de `RelationType`. Le
-nom de la classe correspond au nom du type. Ensuite le corps de la classe
-contient la description des propriétés de ce type de relation, ainsi
-qu'éventuellement une chaine pour le sujet et une autre pour l'objet permettant
-de créer des définitions de relations associées (auquel cas il est possibles de
-donner sur la classe les propriétés de définition de relation explicitées
-ci-dessus), par exemple ::
-
- class verrouille_par(RelationType):
- """relation sur toutes les entités applicatives indiquant que celles-ci sont vérouillées
- inlined = True
- cardinality = '?*'
- subject = '*'
- object = 'CWUser'
-
-En plus des permissions, les propriétés propres aux types de relation (et donc
-partagés par toutes les définitions de relation de ce type) sont :
-
-* `inlined` : booléen contrôlant l'optimisation physique consistant à stocker la
- relation dans la table de l'entité sujet au lieu de créer une table spécifique
- à la relation. Cela se limite donc aux relations dont la cardinalité
- sujet->relation->objet vaut 0..1 ('?') ou 1..1 ('1')
-
-* `symmetric` : booléen indiquant que la relation est symétrique, i.e. "X relation
- Y" implique "Y relation X"
-
-Dans le cas de définitions de relations simultanée, `sujet` et `object` peuvent
-tout deux valoir la même chose que décrite pour le 1er argument de
-`SubjectRelation` et `ObjectRelation`.
-
-A partir du moment où une relation n'est ni mise en ligne, ni symétrique, et
-ne nécessite pas de permissions particulières, sa définition (en utilisant
-`SubjectRelation` ou `ObjectRelation`) est suffisante.
-
-
-Définition des permissions
---------------------------
-
-La définition des permissions se fait à l'aide de l'attribut `permissions` des
-types d'entité ou de relation. Celui-ci est un dictionnaire dont les clés sont
-les types d'accès (action), et les valeurs les groupes ou expressions autorisées.
-
-Pour un type d'entité, les actions possibles sont `read`, `add`, `update` et
-`delete`.
-
-Pour un type de relation, les actions possibles sont `read`, `add`, et `delete`.
-
-Pour chaque type d'accès, un tuple indique le nom des groupes autorisés et/ou
-une ou plusieurs expressions RQL devant être vérifiées pour obtenir
-l'accès. L'accès est donné à partir du moment où l'utilisateur fait parti d'un
-des groupes requis ou dès qu'une expression RQL est vérifiée.
-
-Les groupes standards sont :
-
-* `guests`
-
-* `users`
-
-* `managers`
-
-* `owners` : groupe virtuel correspondant au propriétaire d'une entité. Celui-ci
- ne peut être utilisé que pour les actions `update` et `delete` d'un type
- d'entité.
-
-Il est également possible d'utiliser des groupes spécifiques devant être pour
-cela créés dans le precreate de l'application (`migration/precreate.py`).
-
-Utilisation d'expression RQL sur les droits en écriture
-```````````````````````````````````````````````````````
-Il est possible de définir des expressions RQL donnant des droits de
-modification (`add`, `delete`, `update`) sur les types d'entité et de relation.
-
-Expression RQL pour les permissions sur un type d'entité :
-
-* il faut utiliser la classe `ERQLExpression`
-
-* l'expression utilisée correspond à la clause WHERE d'une requête RQL
-
-* dans cette expression, les variables X et U sont des références prédéfinies
- respectivement sur l'entité courante (sur laquelle l'action est vérifiée) et
- sur l'utilisateur ayant effectué la requête
-
-* il est possible d'utiliser dans cette expression les relations spéciales
- "has_<ACTION>_permission" dont le sujet est l'utilisateur et l'objet une
- variable quelquonque, signifiant ainsi que l'utilisateur doit avoir la
- permission d'effectuer l'action <ACTION> sur la ou les entités liées cette
- variable
-
-Pour les expressions RQL sur un type de relation, les principes sont les mêmes
-avec les différences suivantes :
-
-* il faut utiliser la classe `RRQLExpression` dans le cas d'une relation non
- finale
-
-* dans cette expression, les variables S, O et U sont des références
- prédéfinies respectivement sur le sujet et l'objet de la relation
- courante (sur laquelle l'action est vérifiée) et sur l'utilisateur
- ayant effectué la requête
-
-* On peut aussi définir des droits sur les attributs d'une entité (relation non
- finale), sachant les points suivants :
-
- - pour définir des expressions rql, il faut utiliser la classe `ERQLExpression`
- dans laquelle X représentera l'entité auquel appartient l'attribut
-
- - les permissions 'add' et 'delete' sont équivalentes. En pratique seul
- 'add'/'read' son pris en considération
-
-
-En plus de cela, le type d'entité `CWPermission` de la librairie standard permet
-de construire des modèles de sécurités très complexes et dynamiques. Le schéma
-de ce type d'entité est le suivant : ::
-
-
- class CWPermission(MetaEntityType):
- """entity type that may be used to construct some advanced security configuration
- """
- name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
- require_group = SubjectRelation('CWGroup', cardinality='+*',
- description=_('groups to which the permission is granted'))
- require_state = SubjectRelation('State',
- description=_("entity'state in which the permission is applyable"))
- # can be used on any entity
- require_permission = ObjectRelation('**', cardinality='*1', composite='subject',
- description=_("link a permission to the entity. This "
- "permission should be used in the security "
- "definition of the entity's type to be useful."))
-
-
-Exemple de configuration extrait de *jpl* ::
-
- ...
-
- class Version(EntityType):
- """a version is defining the content of a particular project's release"""
-
- permissions = {'read': ('managers', 'users', 'guests',),
- 'update': ('managers', 'logilab', 'owners',),
- 'delete': ('managers', ),
- 'add': ('managers', 'logilab',
- ERQLExpression('X version_of PROJ, U in_group G,'
- 'PROJ require_permission P, P name "add_version",'
- 'P require_group G'),)}
-
- ...
-
- class version_of(RelationType):
- """link a version to its project. A version is necessarily linked to one and only one project.
- """
- permissions = {'read': ('managers', 'users', 'guests',),
- 'delete': ('managers', ),
- 'add': ('managers', 'logilab',
- RRQLExpression('O require_permission P, P name "add_version",'
- 'U in_group G, P require_group G'),)
- }
- inlined = True
-
-Cette configuration suppose indique qu'une entité `CWPermission` de nom
-"add_version" peut-être associée à un projet et donner le droit de créer des
-versions sur ce projet à des groupes spécifiques. Il est important de noter les
-points suivants :
-
-* dans ce cas il faut protéger à la fois le type d'entité "Version" et la
- relation liant une version à un projet ("version_of")
-
-* du fait de la généricité du type d'entité `CWPermission`, il faut effectuer
- l'unification avec les groupes et / ou les états le cas échéant dans
- l'expression ("U in_group G, P require_group G" dans l'exemple ci-dessus)
-
-
-Utilisation d'expression RQL sur les droits en lecture
-``````````````````````````````````````````````````````
-Les principes sont les mêmes mais avec les restrictions suivantes :
-
-* on ne peut de `RRQLExpression` sur les types de relation en lecture
-
-* les relations spéciales "has_<ACTION>_permission" ne sont pas utilisables
-
-
-Note sur l'utilisation d'expression RQL sur la permission 'add'
-```````````````````````````````````````````````````````````````
-L'utilisation d'expression RQL sur l'ajout d'entité ou de relation pose
-potentiellement un problème pour l'interface utilisateur car si l'expression
-utilise l'entité ou la relation à créer, on est pas capable de vérifier les
-droits avant d'avoir effectué l'ajout (noter que cela n'est pas un problème coté
-serveur rql car la vérification des droits est effectuée après l'ajout
-effectif). Dans ce cas les méthodes de vérification des droits (check_perm,
-has_perm) peuvent inidquer qu'un utilisateur n'a pas le droit d'ajout alors
-qu'il pourrait effectivement l'obtenir. Pour palier à ce soucis il est en général
-nécessaire dans tel cas d'utiliser une action reflétant les droits du schéma
-mais permettant de faire la vérification correctement afin qu'elle apparaisse
-bien le cas échéant.
--- a/goa/doc/devmanual_fr/sect_erudi-ctl.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-L'outil `cubicweb-ctl`
--------------------
-`cubicweb-ctl` est le couteau suisse pour la gestion d'instances CubicWeb.
-La syntaxe générale est ::
-
- cubicweb-ctl <commande> [options commande] <arguments commandes>
-
-Pour voir les commandes disponibles ::
-
- cubicweb-ctl
- cubicweb-ctl --help
-
-A noter que les commandes disponibles varient en fonction des parties de CubicWeb
-qui sont installées.
-
-Pour voir l'aide pour une commande spécifiques ::
-
- cubicweb-ctl <commande> --help
-
-Commandes pour la création d'un composant
-````````````````````````````````````````
-* ``newtemplate``, crée un nouveau composant sur le système de fichiers
- à partir du nom passé en paramètre. Cette commande crée le composant à partir
- d'une squelette d'application, incluant également les fichiers pour le
- packaging debian)
-
-Commandes pour la création d'une instance
-`````````````````````````````````````````
-* ``create``, crée les fichiers de configuration d'une instance
-* ``db-create``, crée la base de données système d'une instance (tables et
- extensions uniquement)
-* ``db-init``, initialise la base de données système d'une instance (schéma,
- groupes, utilisateurs, workflows...)
-
-Par défaut ces trois commandes sont enchainées.
-
-Commandes pour le lancement des instances
-`````````````````````````````````````````
-* ``start``, démarre une, plusieurs, ou toutes les instances
-* ``stop``, arrêt une, plusieurs, ou toutes les instances
-* ``restart``, redémarre une, plusieurs, ou toutes les instances
-* ``status``, donne l'état des instances
-
-Commandes pour la maintenance des instances
-```````````````````````````````````````````
-* ``upgrade``, lance la migration d'instance(s) existante(s) lorsqu'une nouvelle
- version d'CubicWeb ou du composant est installée
-* ``shell``, ouvre un shell de migration pour maintenance manuelle d'une instance
-* ``db-dump``, crée un dump de la base de données système
-* ``db-restore``, restore un dump de la base de données système
-* ``db-check``, vérifie l'intégrité des données d'une instance. Si la correction
- automatique est activée, il est conseillé de faire un dump avant cette
- opération
-* ``schema-sync``, , synchronise le schéma persistent d'une instance avec le schéma
- de l'application. Il est conseillé de faire un dump avant cette opération
-
-Commandes pour la maintenance des catalogues i18n
-`````````````````````````````````````````````````
-* ``i18ncubicweb``, regénère les catalogues de messages de la librairie CubicWeb
-* ``i18ncube``, regénère les catalogues de messages d'un composant
-* ``i18ninstance``, recompile les catalogues de messages d'une instance. Cela est
- effectué automatiquement lors d'une upgrade
-
-Cf Internationalisation_.
-
-Autres commandes
-````````````````
-* ``list``, donne la liste des configurations, des composants et des instances
- disponibles
-* ``delete``, supprime une instance (fichiers de configuration et base de données)
--- a/goa/doc/devmanual_fr/sect_installation.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-Installation de cubicweb et de ses dépendances
--------------------------------------------
-Tout le système CubicWeb est préparé pour l'installation sur une machine
-debian. L'installation manuelle est un peu pénible du fait des nombreuses
-dépendances à installer (twisted, postgres, autres paquets python...). Nous
-supposerons donc ici que l'installation se fait sur une machine debian ayant
-dans ses sources apt un entrepôt contenant les paquets pour CubicWeb.
-
-Pour tout installer sur le système ::
-
- apt-get install cubicweb
-
-On peut également n'installer que les paquets cubicweb-server ou cubicweb-twisted pour
-n'avoir que la partie serveur ou client web sur une machine.
-
-Pour tout installer la documentation et les librairies/outils de développement ::
-
- apt-get install cubicweb-documentation cubicweb-dev
-
-On pourra ensuite installer les paquets suivants :
-
-* `pyro` si vous voulez que l'entrepôt soit accessible via Pyro ou si le client
- et le serveur ne sont pas sur la même machine (auquel cas il faut installer ce
- paquet sur les machines clientes et serveur)
-
-* `python-ldap` si vous voulez utiliser une source ldap sur le serveur
-
-* `postgresql-8.1`, `postgresql-contrib-8.1` et `postgresql-plpython-8.1` la
- machine devant héberger la base de données système
-
-Configuration de l'environnement
---------------------------------
-Ajouter les lignes suivantes à son `.bashrc` ou `.bash_profile` pour configurer
-votre environnement de développement ::
-
- export CW_REGISTRY=~/etc/cubicweb.d/
- export CW_CUBES=~/hg/
- export CW_RUNTIME=/tmp/
-
-Cela suppose que le composant cubicweb que vous développez est dans un
-sous-répertoire de *~/hg/* et que vous avez créé le répertoire *~/etc/cubicweb.d/*
-pour que `cubicweb-ctl` y place vos instances de test.
-
-
-Configuration Postgres
-----------------------
-* création d'un super utilisateur pour la création d'instance (**root**) ::
-
- createuser --superuser --createdb -P pgadmin
-
- Un mot de passe de connection pour cet utilisateur vous sera demandé. Il
- faudra utiliser ce login / mot de passe à la création d'instance via
- `cubicweb-ctl`
-
-* installation des extensions pour l'index plein texte ::
-
- cat /usr/share/postgresql/8.1/contrib/tsearch2.sql | psql -U pgadmin template1
-
-* installation du langage plpythonu par défaut ::
-
- createlang -U pgadmin plpythonu template1
-
-
-Configuration Pyro
-------------------
-Si vous utilisez Pyro, il est nécessaire d'avoir un serveur de noms Pyro
-tournant sur votre réseau (par défaut celui-ci est repéré par une requête
-broadcast). Pour cela il faut soit :
-
-* le lancer à la main avant le démarrage de cubicweb avec la commande `pyro-ns`
-
-* le lancer à la main avant le démarrage de cubicweb sous forme d'un serveur avec
- la commande `pyro-nsd start`
-
-* éditer le fichier */etc/default/pyro-nsd* pour que le serveur de nom pyro soit
- lancé automatiquement au démarrage de la machine
--- a/goa/doc/devmanual_fr/sect_mercurial.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-Présentation de Mercurial
--------------------------
-
-Introduction
-````````````
-Mercurial_ gère un ensemble distribué d'entrepôts contenant des arbres de
-révisions (chaque révision indique les changements à effectuer pour obtenir la
-version suivante, et ainsi de suite). Localement, on dispose d'un entrepôt
-contenant un arbre de révisions, et d'un répertoire de travail. Il est possible
-de mettre dans son répertoire de travail, une des versions issue de son entrepôt
-local, de la modifier puis de la verser dans son entrepôt. Il est également
-possible de récuprer dans son entrepôt local des révisions venant d'un autre
-entrepôt, ou d'exporter ses propres révisions depuis son entrepôt local vers un
-autre entrepôt.
-
-A noter que contrairement à CVS/Subversion, on crée généralement un entrepôt par
-projet à gérer.
-
-Lors d'un développement collaboratif, on crée généralement un entrepôt central
-accessible à tout les développeurs du projet. Ces entrepôts centraux servent de
-référence. Selon ses besoins, chacun peut ensuite disposer d'un entrepôt local,
-qu'il faudra penser à synchroniser avec l'entrepôt central de temps à autre.
-
-
-Principales commandes
-`````````````````````
-* Créer un entrepôt local ::
-
- hg clone ssh://orion//home/src/prive/rep
-
-* Voir le contenu de l'entrepôt local (outil graphique en Tk) ::
-
- hg view
-
-* Ajouter un sous-répertoire ou un fichier dans le répertoire courant ::
-
- hg add rep
-
-* Placer dans son répertoire de travail une révision spécifique (ou la dernière
- revision) issue de l'entrepôt local ::
-
- hg update [identifiant-revision]
- hg up [identifiant-revision]
-
-* Récupérer dans son entrepôt local, l'arbre de révisions contenu dans un
- entrepôt distant (cette opération ne modifie pas le répertoire local) ::
-
- hg pull ssh://orion//home/src/prive/rep
- hg pull -u ssh://orion//home/src/prive/rep # équivalent à pull + update
-
-* Voir quelles sont les têtes de branches de l'entrepôt local si un `pull` a
- tiré une nouvelle branche ::
-
- hg heads
-
-* Verser le répertoire de travail dans l'entrepôt local (et créer une nouvelle
- révision) ::
-
- hg commit
- hg ci
-
-* Fusionner, avec la révision mère du répertoire local, une autre révision issue
- de l'entrepôt local (la nouvelle révision qui en résultera aura alors deux
- révisions mères) ::
-
- hg merge identifiant-revision
-
-* Exporter dans un entrepôt distant, l'arbre de révisions contenu dans son
- entrepôt local (cette opération ne modifie pas le répertoire local) ::
-
- hg push ssh://orion//home/src/prive/rep
-
-* Voir quelle sont les révisions locales non présentes dans un autre entrepôt ::
-
- hg outgoing ssh://orion//home/src/prive/rep
-
-* Voir quelle sont les révisions d'un autre entrepôt non présentes localement ::
-
- hg incoming ssh://orion//home/src/prive/rep
-
-* Voir quelle est la révision issue de l'entrepôt local qui a été sortie dans le
- répertoire de travail et modifiée ::
-
- hg parent
-
-* Voir les différences entre le répertoire de travail et la révision mère de
- l'entrepôt local, éventuellement permettant de les verser dans l'entrepôt
- local ::
-
- hg diff
- hg commit-tool
- hg ct
-
-
-Bonnes pratiques
-````````````````
-* penser à faire un `hg pull -u` régulièrement et particulièrement avant de
- faire un `hg commit`
-
-* penser à faire un `hg push` lorsque votre entrepôt contient une version
- relativement stable de vos modifications
-
-* si un `hg pull -u` a créé une nouvelle tête de branche :
-
- 1. identifier l'identifiant de celle-ci avec `hg head`
- 2. fusionner avec `hg merge`
- 3. `hg ci`
- 4. `hg push`
-
-.. _Mercurial: http://www.selenic.com/mercurial/
--- a/goa/doc/devmanual_fr/sect_stdlib_schemas.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-Schémas prédéfinies dans la librairie
--------------------------------------
-
-La librairie définit un certain nombre de schémas d'entités nécessaires
-au système ou bien couramment utilisées dans les application `cubicweb`.
-Vous pouvez bien entendu étendre ces schémas au besoin.
-
-
-Schémas "systèmes"
-``````````````````
-
-* `CWUser`, utilisateurs du système
-* `CWGroup`, groupes d'utilisateurs
-* `CWEType`, types d'entité
-* `CWRType`, types de relation
-
-* `State`, état d'un workflow
-* `Transition`, transition d'un workflow
-* `TrInfo`, enregistrement d'un passage de transition pour une entité
-
-* `EmailAddress`, adresse électronique, utilisé par le système de notification
- pour les utilisateurs et par d'autres schéma optionnels
-
-* `CWProperty`, utilisé pour configurer l'application
-* `CWPermission`, utilisé pour configurer la sécurité de l'application
-
-* `Card`, fiche documentaire générique
-* `Bookmark`, un type d'entité utilisé pour permetter à un utilisateur de
- personnaliser ses liens de navigation dans l'application.
-
-
-Composants de la librairie
-``````````````````
-Une application est construite sur la base de plusieurs composants de base.
-Parmi les composants de base disponible, on trouve par exemple :
-
-* `ecomment`, fournit le type d'entité `Comment` permettant de commenter les
- entités du site
-
-* `emailinglist`, fournit le type d'entité `Mailinglist` regroupant des
- informations sur une liste de discussion
-
-* `efile`, fournit les types d'entités `File` et `Image` utilisés pour
- représenter des fichiers (texte ou binaire) avec quelques données
- supplémentaires comme le type MIME ou l'encodage le cas échéant ().
-
-* `elink`, fournit le type d'entité lien internet (`Link`)
-
-* `eblog`, fournit le type d'entité weblog (`Blog`)
-
-* `eperson`, fournit le type d'entité personne physique (`Person`)
-
-* `eaddressbook`, fournit les types d'entités utilisés pour représenter des n°
- de téléphone (`PhoneNumber`) et des adresses postales (`PostalAddress`)
-
-* `eclasstags`, système de classfication à base d'étiquettes (`Tag`)
-
-* `eclassfolders`, système de classification à base de dossiers hiérarchiques
- destinés à créer des rubriques de navigation (`Folder`)
-
-* `eemail`, gestion d'archives de courriers électroniques (`Email`, `Emailpart`,
- `Emailthread`)
-
-* `ebasket`, gestion de paniers (`Basket`) permettant de regrouper des entités
-
-Pour déclarer l'utilisation d'un composant, une fois celui-ci installé, ajoutez
-le nom du composant à la variable `__use__` du fichier `__pkginfo__.py` de
-votre propre composant.
--- a/goa/doc/devmanual_fr/sect_stdlib_vues.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-
-Vues prédéfinies dans la librairie
-----------------------------------
-Un certain nombre de vues sont utilisées pour construire l'interface web, qui
-s'appliquent à une ou plusieurs entités. On les distingue par leur identifiant,
-et les principales sont :
-
-:primary:
- vue principale pour une entité, elle est appelée par défaut lorsqu'il n'y a
- qu'un seul élément correspondant à la recherche. Cette vue est censée
- afficher le maximum d'informations à propos de l'objet.
-:secondary:
- vue secondaire d'une entité. Par défaut, Elle affiche les deux premiers
- attributs de l'entité sous la forme d'un lien cliquable amenant sur la vue
- primaire.
-:oneline:
- similaire à la vue `secondary`, mais appelée dans des cas où l'on désire que
- la vue tient sur une ligne, ou de manière générale juste avoir une vue plus
- abbrégée. Par défaut, cette vue utilise le paramètre de configuration
- `MAX_LINE_CHAR` pour contrôler la taille du résultat.
-:text:
- similaire à la vue `oneline`, mais ne devant pas contenir de html.
-:incontext, outofcontext:
- similaire à la vue `secondary`, mais appelé si l'entité est considérée comme
- en dehors ou dans son contexte. Par défault renvoie respectivement le
- résultat de `textincontext` et `textoutofcontext` entouré par un lien
- permettant d'accéder à la vue primaire de l'entité
-:textincontext, textoutofcontext:
- similaire à la vue `text`, mais appelé si l'entité est considérée comme
- en dehors ou dans son contexte. Par défault renvoie respectivement le
- résultat des méthodes `.dc_title` et `.dc_long_title` de l'entité
-:list:
- crée une liste html (<ul>) et appelle la vue `listitem` pour chaque entité
-:listitem:
- redirige par défaut vers la vue `outofcontext`
-:rss:
- crée unvue RSS/XML et appelle la vue `rssitem` pour chaque entité
-:rssitem:
- crée unvue RSS/XML pour une entité à partir des résultats renvoyés par les
- méthodes dublin core de l'objet (`dc_*`)
-
-Vues de départ :
-
-:index:
- page d'acceuil
-:schema:
- affiche le schéma de l'application
-
-Vues particulières :
-
-:noresult:
- appelé si le result set est vide
-:finall:
- affiche la valeur de la cellule sans transformation (dans le cas d'une
- entité non finale, on voit son eid). Appelable sur n'importe quel result
- set.
-:table:
- crée une table html (<table>) et appelle la vue `cell` pour chaque cellule
- du résultat. Appelable sur n'importe quel result set.
-:cell:
- par défaut redirige sur la vue `final` si c'est une entité finale
- ou sur la vue `outofcontext` sinon
-:null:
- vue toujours appelable et ne retournant rien
--- a/goa/doc/quickstart.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Introduction
-=============
-
-
-Concepts et vocabulaire
------------------------
-
-*schéma*
- le schéma définit le modèle de données d'une application sous forme
- d'entités et de relations. C'est l'élément central d'une
- application.
-
-*result set*
- objet qui encaspule les résultats d'une requête adressée à l'entrepôt
- de données et des informations sur cette requête.
-
-*vue*
- une vue est une manière de représenter les données d'un `result set`
- sous forme HTML, CSV, JSON, etc.
-
-
-
-Définition d'une application de Blog
-====================================
-
-La première chose à faire est de copier le squelette depuis le répertoire
-``lax/skel`` vers un nouveau répertoire qui sera votre application
-``Google AppEngine``::
-
- $ cp -r lax/skel myapp
-
-Définition du schéma
---------------------
-
-Ouvrir le fichier ``myapp/schema.py`` afin de définir le schéma des
-données manipulées. La syntaxe de la définition est la même que celle
-proposée par `Google AppEngine`_ mais il faut remplacer la ligne
-d'import::
-
- from google.appengine.ext import db
-
-par celle-ci::
-
- from cubicweb.goa import db
-
-
-Un exemple de schéma de données pour un ``Blog`` pourrait être::
-
- from cubicweb.goa import db
-
- class Blog(db.Model):
- # un titre à donner à l'entrée
- title = db.StringProperty(required=True)
- # la date à laquelle le blog est créé
- diem = db.DateProperty(required=True, auto_now_add=True)
- # le contenu de l'entrée
- content = db.TextProperty()
- # une entrée peut en citer une autre
- cites = db.SelfReferenceProperty()
-
-
-Personnalisation des vues
--------------------------
-
-``LAX`` permet de générer directement, à partir de la définition
-du schéma, des vues de consultation, d'ajout et de modification
-pour tous les types de donées manipulés. Il est toutefois
-généralement souhaitable de personnaliser les vues de consultations.
-
-Dans ``LAX``, les vues sont représentées par des classes Python.
-
-Une vue se caractérise par :
-
-- un identifiant (tous les objets dans ``LAX`` sont enregistrés
- dans un registre et cet identifiant sert de clé pour y retrouver
- la vue)
-
-- une description des types de données auxquels elle s'applique
-
-Il existe dans ``LAX`` des vues prédéfinies et utilisées par le moteur
-d'affichage. Pour avoir une liste exhaustive de ces vues prédéfinies,
-vous pouvez consulter cette page. (XXX mettre le lien vers la liste).
-Par exemple, la vue ``primary`` est la vue utilisée pour générer la
-page principale de consultation d'un objet.
-
-Par exemple, si on souhaite modifier la page principale d'une entrée de
-blog, il faut surcharger la vue ``primary`` des objets ``Blog`` dans
-le fichier ``myapp/views.py``::
-
- from cubicweb.web.views import baseviews
-
- class BlogPrimaryView(baseviews.PrimaryView):
- accepts = ('Blog',)
-
- def cell_call(self, row, col):
- entity = self.rset.get_entity(row, col)
- self.w(u'<h1>%s</h1>' % entity.title)
- self.w(u'<div>%s</div>' entity.content)
-
-
-Génération du graphique de schéma
----------------------------------
-
-Il existe une vue ``schema`` qui permet d'afficher un graphique
-représantant les différents types d'entités définis dans le schéma
-ainsi que les relations entre ces types. Ce graphique doit être généré
-statiquement. Le script à utiliser pour générer ce schéma est
-dans ``myapp/tools``. Ce script nécessite d'avoir accès aux
-bibliothèques fournies par le SDK de ``Google AppEngine``. Il faut
-donc modifier son PYTHONPATH::
-
- $ export PYTHONPATH=GAE_ROOT/google:GAE_ROOT/lib/yaml
- $ python tools/generate_schema_img.py
-
-
-Génération des fichiers de traduction
--------------------------------------
-
-Des catalogues de traduction se trouvent dans `myapp/i18n`. Il faut
-pour l'instant les mettre à jour à la main (et/ou avec les outils
-``GNU`` comme ``xgettext``) et ensuite les compiler grâce au script
-``myapp/tools/i18ncompile.py``::
-
- $ python tools/i18ncompile.py
-
-.. _`Google AppEngine` :: http://code.google.com/appengine/docs/datastore/overview.html
--- a/goa/doc/tutorial-wine.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-=============
-LAX Tutorial
-=============
-
-Introduction
-------------
-
-LAX is a web framework on top of the Google AppEngine datastore.
-
-
-features: schema/data-model at core of app, selection/view mechanism,
-reuseable components, very fast development
-
-
-Since we are french, let us develop an example application that deals
-with wine and will allow any wine enthusiast to track the content of
-its cellar and share his tasting experiences.
-
-Schema
-------
-
-With LAX, the core of the application is the schema/datamodel.
-
-laxctl newapp ? XXX
-
-We will start by something simple and define three entities: WineMaker,
-Wine and Bottle.
-
-::
-
- class WineMaker(EntityType):
- name = String(maxsize=50, required=True)
-
- class Wine(EntityType):
- name = String(required=True, maxsize=100, fulltextindexed=True)
- vintage = Int(required=True, constraints=[IntervalBoundConstraint(1850,2100)])
- grown_by = SubjectRelation('WineMaker', cardinality='?*',
- description=_('Winemaker who grew the wine'))
-
- class Bottle(EntityType):
- buy_date = Date(description=_('Date when the bottle was bought.'),
- default='TODAY')
- bottle_of = SubjectRelation('Wine', cardinality='?*')
-
-A WineMaker only has a name which is a string that is required and
-must be less than 50 characters.
-
-A Wine has a name, which is a string that is required, must be less
-than 100 characters and will be indexed in the full-text index XXX
-fulltextindex marche pas encore. A Wine
-also has a vintage year which is an integer that is required and must
-be between 1850 and 2100. A Wine also has a relationship ``grown_by``
-that link it to a WineMaker. Cardinality ``?*`` means that a Wine can
-have zero or one WineMaker (``?`` means `zero or one`) and that a
-WineMaker can have any number of Wine entities (``*`` means `any number
-including zero`).
-
-A Bottle has a buy_date attribute, which is a date with a default
-value of TODAY, meaning that when a new bottle is created, it will
-have its creation date as buy_date unless the user changes it to some
-other date. A Bottle also has a relationship ``bottle_of`` that link
-it to a Wine. The cardinality of that relationship implies that a
-Bottle can be linked to zero or one Wine and that a Wine can by linked
-to any number of Bottle entities.
-
-
-Defining this simple schema is enough to get us started, launch the
-application with the command::
-
- laxctl start Winopedia
-
-and point your browser at localhost:8080
-
-You will see the home page of your application. It lists the entity
-types: WineMaker, Wine, Bottle.
-
-Let us create a few of these. Click on the [+] at the right of the
-link WineMaker. Call this new WineMaker ``Domaine du château`` and
-validate the form by clicking on ``button_ok``.
-
-Click on the logo at top left to get back to the home page, then
-follow the WineMaker link. You should be seeing a list with a single
-item ``Domaine du château``. Clicking on this item will get you to
-its detailed description except that in this case, there is not much
-to display besides the name.
-
-Now get back to the home page by clicking on the top-left logo, then
-create a new WineMaker called ``Vallon de la Dame`` and get back to the
-home page again to follow the WineMaker link for the second time. The
-list now has two items.
-
-Get back to the home page and click on [+] at the right of the link
-Wine. Call this new wine ``Cuvée du Roi`` and enter 2008 as vintage,
-then click on ``button_ok``. You added a new wine without saying who
-made it. There is a box on the left entitled "actions", click on the
-menu item `modify`. You are back to the form to edit the wine entity
-you just created, except that the form now has another section with a
-combobox titled "add a relationship". Chose "grown_by" in this
-menu and a second combobox appears where you pick ``Domaine du
-château``. Validate the changes by clicking ``button_ok``. The entity
-Wine that is displayed now includes a link to the entity WineMaker
-named ``Domaine du château``.
-
-Exercise
-~~~~~~~~
-
-Create new entities Wine and Bottle.
-
-What we learned
-~~~~~~~~~~~~~~~
-
-Creating a simple schema was enough to set up a new application that
-can store WineMaker, Wine, Bottle.
-
-What is next ?
---------------
-
-Althought the application is fully functionnal, its look is very
-basic. We will now improve how information is displayed by writing
-views.
-
-
-Views
-======
-
-...
-
-Defining views with selection/views
-
-implementing interfaces, calendar for bottles bought and for tasting.
-calendar with export icalput attribute drink_date on bottle
-
-add attribute wine color
-
-create view "bottle table" with color, buy_date, drink_date.
-
-in view wine, select Wine.bottles and apply view "bottle table"
-
-demo ajax with filter on bottle table
-
-Components
-===========
-
-...
-
-
-
-customize MainTemplate
-
-rss channel of new bottles or wines
-
-use URLRewriting for nice urls
-
-talk about security access rights
-
-talk about rql
\ No newline at end of file
--- a/goa/doc/tutorial.en.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,227 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-=============
-LAX Tutorial
-=============
-
-Introduction
-============
-
-LAX stands for Logilab App engine eXtension. It is a web framework
-running on top of the Google AppEngine datastore.
-
-Distinctive features include a data-model driven engine, a query
-language, a selection/view mechanism for HTML/XML/text generation,
-reuseable components, etc. It all sums up to very fast and efficient
-development.
-
-This tutorial will guide you to build a blog application step by step
-to discover the unique features of LAX. It assumes that you followed
-the installation guidelines and that both the AppEngine SDK and the
-LAX framework are setup on your computer.
-
-Creating a very simple application
-==================================
-
-Creating a new application
---------------------------
-
-When you installed lax, you saw a directory named skel. Make a copy of
-this directory and call it BlogDemo.
-
-Defining a schema
------------------
-
-With LAX, the schema/datamodel is the core of the application.
-
-Let us start with something simple and improve on it later. First, we
-make sure that in appconfig.py we have a line ::
-
- schema_type = 'yams'
-
-Then, in schema.py, we define two entities : ``Blog`` and ``BlogEntry``.
-
-::
-
- class Blog(EntityType):
- title = String(maxsize=50, required=True)
- description = String()
-
- class BlogEntry(EntityType):
- title = String(maxsize=100, required=True)
- publish_date = Date(default='TODAY')
- text = String(fulltextindexed=True)
- category = String(vocabulary=('important','business'))
- entry_of = SubjectRelation('Blog', cardinality='?*')
-
-A Blog has a title and a description. The title is a string that is
-required and must be less than 50 characters. The description is a
-string that is not constrained.
-
-A BlogEntry has a title, a publish_date and a text. The title is a
-string that is required and must be less than 100 characters. The
-publish_date is a Date with a default value of TODAY, meaning that
-when a BlogEntry is created, its publish_date will be the current day
-unless it is modified. The text is a string that will be indexed in
-the full-text index and has no constraint.
-
-A BlogEntry also has a relationship ``entry_of`` that link it to a
-Blog. The cardinality ``?*`` means that a BlogEntry can be part of
-zero or one Blog (``?`` means `zero or one`) and that a Blog can
-have any number of BlogEntry (``*`` means `any number including
-zero`). For completeness, remember that ``+`` means `one or more`.
-
-:note: in lax-0.3.0, cardinality checking is not fully ported to
-AppEngine, so cardinality limits are not enforced. This should be
-fixed in lax-0.4.0 available at the beginning of June.
-
-Using the application
----------------------
-
-Defining this simple schema is enough to get us started. Launch the
-application with the command::
-
- python dev_appserver.py BlogDemo
-
-and point your browser at localhost:8080
-
-You will see the home page of your application. It lists the entity
-types: Blog and BlogEntry.
-
-Let us create a few of these. Click on the [+] at the right of the
-link Blog. Call this new Blog ``Tech-blog`` and type in
-``everything about technology`` as the description, then validate the
-form by clicking on ``button_ok``.
-
-Click on the logo at top left to get back to the home page, then
-follow the Blog link. If this link reads ``blog_plural`` it is because
-i18n is not working for you yet. Let us ignore this for a while. After
-following the link, you should be seeing a list with a single item
-``Tech-blog``. Clicking on this item will get you to its detailed
-description except that in this case, there is not much to display
-besides the name and the phrase ``everything about technology``.
-
-Now get back to the home page by clicking on the top-left logo, then
-create a new Blog called ``MyLife`` and get back to the home page
-again to follow the Blog link for the second time. The list now
-has two items.
-
-Get back to the home page and click on [+] at the right of the link
-BlogEntry. Call this new entry ``Hello World`` and type in some text
-before clicking on ``button_ok``. You added a new blog entry without
-saying to what blog it belongs. There is a box on the left entitled
-``actions``, click on the menu item ``modify``. You are back to the form
-to edit the blog entry you just created, except that the form now has
-another section with a combobox titled ``add relation``. Chose
-``entry_of`` in this menu and a second combobox appears where you pick
-``MyLife``. Validate the changes by clicking
-``button_ok``. The entity BlogEntry that is displayed now includes a link
-to the entity Blog named ``MyLife``.
-
-Conclusion
-----------
-
-Exercise
-~~~~~~~~
-
-Create new blog entries in ``Tech-blog``.
-
-What we learned
-~~~~~~~~~~~~~~~
-
-Creating a simple schema was enough to set up a new application that
-can store blogs and blog entries.
-
-What is next ?
---------------
-
-Althought the application is fully functionnal, its look is very
-basic. We will now improve how information is displayed by writing
-views.
-
-
-Developing the user interface with Views
-========================================
-
-[WRITE ME]
-
-* Defining views with selection/views
-
-* implementing interfaces, calendar for blog entries.
-
-* show that a calendar view can export data to ical.
-
-* create view "blogentry table" with title, publish_date, category.
-
-* in view blog, select blogentries and apply view "blogentry table"
-
-* demo ajax by filtering blogentry table on category
-
-Components
-===========
-
-[WRITE ME]
-
-* explain the component architecture
-
-* add comments to the blog by importing the comments component
-
-Boxes
-======
-
-[WRITE ME]
-
-* explain how to build a box
-
-* add an blogentry archives box
-
-Preferences
-============
-
-[WRITE ME]
-
-* talk about the user preferences
-
-* add an example on how to hide / display / move a component or a box
-
-MainTemplate
-============
-
-[WRITE ME]
-
-* customize MainTemplate and show that everything in the user
- interface can be changed
-
-
-RSS Channel
-===========
-
-[WRITE ME]
-
-* show that the RSS view can be used to display an ordered selection
- of blog entries, thus providing a RSS channel
-
-* show that a different selection (by category) means a different channel
-
-RQL
-====
-
-[WRITE ME]
-
-* talk about the Relation Query Language
-
-URL Rewriting
-=============
-
-[WRITE ME]
-
-* show how urls are mapped to selections and views and explain URLRewriting
-
-Security
-=========
-
-[WRITE ME]
-
-* talk about security access rights and show that security is defined
- using RQL
-
--- a/goa/gaesource.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,331 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""Adapter for google appengine source.
-
-"""
-__docformat__ = "restructuredtext en"
-
-from cubicweb import AuthenticationError, UnknownEid
-from cubicweb.server.sources import AbstractSource, ConnectionWrapper
-from cubicweb.server.pool import SingleOperation
-from cubicweb.server.utils import crypt_password
-from cubicweb.goa.dbinit import set_user_groups
-from cubicweb.goa.rqlinterpreter import RQLInterpreter
-
-from google.appengine.api.datastore import Key, Entity, Put, Delete
-from google.appengine.api import datastore_errors, users
-
-def _init_groups(guser, euser):
- # set default groups
- if guser is None:
- groups = ['guests']
- else:
- groups = ['users']
- if users.is_current_user_admin():
- groups.append('managers')
- set_user_groups(euser, groups)
-
-def _clear_related_cache(session, gaesubject, rtype, gaeobject):
- subject, object = str(gaesubject.key()), str(gaeobject.key())
- for eid, role in ((subject, 'subject'), (object, 'object')):
- # clear related cache if necessary
- try:
- entity = session.entity_cache(eid)
- except KeyError:
- pass
- else:
- entity.cw_clear_relation_cache(rtype, role)
- if gaesubject.kind() == 'CWUser':
- for asession in session.repo._sessions.itervalues():
- if asession.user.eid == subject:
- asession.user.cw_clear_relation_cache(rtype, 'subject')
- if gaeobject.kind() == 'CWUser':
- for asession in session.repo._sessions.itervalues():
- if asession.user.eid == object:
- asession.user.cw_clear_relation_cache(rtype, 'object')
-
-def _mark_modified(session, gaeentity):
- modified = session.transaction_data.setdefault('modifiedentities', {})
- modified[str(gaeentity.key())] = gaeentity
- DatastorePutOp(session)
-
-def _rinfo(session, subject, rtype, object):
- gaesubj = session.datastore_get(subject)
- gaeobj = session.datastore_get(object)
- rschema = session.vreg.schema.rschema(rtype)
- cards = rschema.rproperty(gaesubj.kind(), gaeobj.kind(), 'cardinality')
- return gaesubj, gaeobj, cards
-
-def _radd(session, gaeentity, targetkey, relation, card):
- if card in '?1':
- gaeentity[relation] = targetkey
- else:
- try:
- related = gaeentity[relation]
- except KeyError:
- related = []
- else:
- if related is None:
- related = []
- related.append(targetkey)
- gaeentity[relation] = related
- _mark_modified(session, gaeentity)
-
-def _rdel(session, gaeentity, targetkey, relation, card):
- if card in '?1':
- gaeentity[relation] = None
- else:
- related = gaeentity[relation]
- if related is not None:
- related = [key for key in related if not key == targetkey]
- gaeentity[relation] = related or None
- _mark_modified(session, gaeentity)
-
-
-class DatastorePutOp(SingleOperation):
- """delayed put of entities to have less datastore write api calls
-
- * save all modified entities at precommit (should be the first operation
- processed, hence the 0 returned by insert_index())
-
- * in case others precommit operations modify some entities, resave modified
- entities at commit. This suppose that no db changes will occurs during
- commit event but it should be the case.
- """
- def insert_index(self):
- return 0
-
- def _put_entities(self):
- pending = self.session.transaction_data.get('pendingeids', ())
- modified = self.session.transaction_data.get('modifiedentities', {})
- for eid, gaeentity in modified.iteritems():
- assert not eid in pending
- Put(gaeentity)
- modified.clear()
-
- def postcommit_event(self):
- self._put_entities()
-
- def precommit_event(self):
- self._put_entities()
-
-
-class GAESource(AbstractSource):
- """adapter for a system source on top of google appengine datastore"""
-
- passwd_rql = "Any P WHERE X is CWUser, X login %(login)s, X upassword P"
- auth_rql = "Any X WHERE X is CWUser, X login %(login)s, X upassword %(pwd)s"
- _sols = ({'X': 'CWUser', 'P': 'Password'},)
-
- options = ()
-
- def __init__(self, repo, appschema, source_config, *args, **kwargs):
- AbstractSource.__init__(self, repo, appschema, source_config,
- *args, **kwargs)
- if repo.config['use-google-auth']:
- self.info('using google authentication service')
- self.authenticate = self.authenticate_gauth
- else:
- self.authenticate = self.authenticate_local
-
- def reset_caches(self):
- """method called during test to reset potential source caches"""
- pass
-
- def init_creating(self):
- pass
-
- def init(self):
- # XXX unregister unsupported hooks
- from cubicweb.server.hooks import sync_owner_after_add_composite_relation
- self.repo.hm.unregister_hook(sync_owner_after_add_composite_relation,
- 'after_add_relation', '')
-
- def get_connection(self):
- return ConnectionWrapper()
-
- # ISource interface #######################################################
-
- def compile_rql(self, rql):
- rqlst = self.repo.vreg.parse(rql)
- rqlst.restricted_vars = ()
- rqlst.children[0].solutions = self._sols
- return rqlst
-
- def set_schema(self, schema):
- """set the instance'schema"""
- self.interpreter = RQLInterpreter(schema)
- self.schema = schema
- if 'CWUser' in schema and not self.repo.config['use-google-auth']:
- # rql syntax trees used to authenticate users
- self._passwd_rqlst = self.compile_rql(self.passwd_rql)
- self._auth_rqlst = self.compile_rql(self.auth_rql)
-
- def support_entity(self, etype, write=False):
- """return true if the given entity's type is handled by this adapter
- if write is true, return true only if it's a RW support
- """
- return True
-
- def support_relation(self, rtype, write=False):
- """return true if the given relation's type is handled by this adapter
- if write is true, return true only if it's a RW support
- """
- return True
-
- def authenticate_gauth(self, session, login, password):
- guser = users.get_current_user()
- # allowing or not anonymous connection should be done in the app.yaml
- # file, suppose it's authorized if we are there
- if guser is None:
- login = u'anonymous'
- else:
- login = unicode(guser.nickname())
- # XXX http://code.google.com/appengine/docs/users/userobjects.html
- # use a reference property to automatically work with email address
- # changes after the propagation feature is implemented
- key = Key.from_path('CWUser', 'key_' + login, parent=None)
- try:
- euser = session.datastore_get(key)
- # XXX fix user. Required until we find a better way to fix broken records
- if not euser.get('s_in_group'):
- _init_groups(guser, euser)
- Put(euser)
- return str(key)
- except datastore_errors.EntityNotFoundError:
- # create a record for this user
- euser = Entity('CWUser', name='key_' + login)
- euser['s_login'] = login
- _init_groups(guser, euser)
- Put(euser)
- return str(euser.key())
-
- def authenticate_local(self, session, login, password):
- """return CWUser eid for the given login/password if this account is
- defined in this source, else raise `AuthenticationError`
-
- two queries are needed since passwords are stored crypted, so we have
- to fetch the salt first
- """
- args = {'login': login, 'pwd' : password}
- if password is not None:
- rset = self.syntax_tree_search(session, self._passwd_rqlst, args)
- try:
- pwd = rset[0][0]
- except IndexError:
- raise AuthenticationError('bad login')
- # passwords are stored using the bytea type, so we get a StringIO
- if pwd is not None:
- args['pwd'] = crypt_password(password, pwd[:2])
- # get eid from login and (crypted) password
- rset = self.syntax_tree_search(session, self._auth_rqlst, args)
- try:
- return rset[0][0]
- except IndexError:
- raise AuthenticationError('bad password')
-
- def syntax_tree_search(self, session, union, args=None, cachekey=None,
- varmap=None):
- """return result from this source for a rql query (actually from a rql
- syntax tree and a solution dictionary mapping each used variable to a
- possible type). If cachekey is given, the query necessary to fetch the
- results (but not the results themselves) may be cached using this key.
- """
- results, description = self.interpreter.interpret(union, args,
- session.datastore_get)
- return results # XXX description
-
- def flying_insert(self, table, session, union, args=None, varmap=None):
- raise NotImplementedError
-
- def add_entity(self, session, entity):
- """add a new entity to the source"""
- # do not delay add_entity as other modifications, new created entity
- # needs an eid
- entity.put()
-
- def update_entity(self, session, entity):
- """replace an entity in the source"""
- gaeentity = entity.to_gae_model()
- _mark_modified(session, entity.to_gae_model())
- if gaeentity.kind() == 'CWUser':
- for asession in self.repo._sessions.itervalues():
- if asession.user.eid == entity.eid:
- asession.user.update(dict(gaeentity))
-
- def delete_entity(self, session, entity):
- """delete an entity from the source"""
- # do not delay delete_entity as other modifications to ensure
- # consistency
- eid = entity.eid
- key = Key(eid)
- Delete(key)
- session.clear_datastore_cache(key)
- session.drop_entity_cache(eid)
- session.transaction_data.get('modifiedentities', {}).pop(eid, None)
-
- def add_relation(self, session, subject, rtype, object):
- """add a relation to the source"""
- gaesubj, gaeobj, cards = _rinfo(session, subject, rtype, object)
- _radd(session, gaesubj, gaeobj.key(), 's_' + rtype, cards[0])
- _radd(session, gaeobj, gaesubj.key(), 'o_' + rtype, cards[1])
- _clear_related_cache(session, gaesubj, rtype, gaeobj)
-
- def delete_relation(self, session, subject, rtype, object):
- """delete a relation from the source"""
- gaesubj, gaeobj, cards = _rinfo(session, subject, rtype, object)
- pending = session.transaction_data.setdefault('pendingeids', set())
- if not subject in pending:
- _rdel(session, gaesubj, gaeobj.key(), 's_' + rtype, cards[0])
- if not object in pending:
- _rdel(session, gaeobj, gaesubj.key(), 'o_' + rtype, cards[1])
- _clear_related_cache(session, gaesubj, rtype, gaeobj)
-
- # system source interface #################################################
-
- def eid_type_source(self, session, eid):
- """return a tuple (type, source, extid) for the entity with id <eid>"""
- try:
- key = Key(eid)
- except datastore_errors.BadKeyError:
- raise UnknownEid(eid)
- return key.kind(), 'system', None
-
- def create_eid(self, session):
- return None # let the datastore generating key
-
- def add_info(self, session, entity, source, extid=None):
- """add type and source info for an eid into the system table"""
- pass
-
- def delete_info(self, session, eid, etype, uri, extid):
- """delete system information on deletion of an entity by transfering
- record from the entities table to the deleted_entities table
- """
- pass
-
- def fti_unindex_entity(self, session, eid):
- """remove text content for entity with the given eid from the full text
- index
- """
- pass
-
- def fti_index_entity(self, session, entity):
- """add text content of a created/modified entity to the full text index
- """
- pass
--- a/goa/goaconfig.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""google appengine configuration
-
-"""
-__docformat__ = "restructuredtext en"
-
-import os
-from os.path import join
-
-from cubicweb import CW_SOFTWARE_ROOT
-from cubicweb.cwconfig import CubicWebConfiguration
-from cubicweb.web.webconfig import WebConfiguration, merge_options
-from cubicweb.server.serverconfig import ServerConfiguration
-from cubicweb.goa.dbmyams import load_schema
-
-UNSUPPORTED_OPTIONS = set(('connections-pool-size',
- 'pyro-host', 'pyro-instance-id',
- 'pyro-ns-host', 'pyro-ns-group',
- 'https-url', 'host', 'pid-file', 'uid', 'base-url', 'log-file',
- 'smtp-host', 'smtp-port',
- 'embed-allowed',
- ))
-
-# XXX fix:
-# * default sender-name / sender-addr value
-# * what about *session-time
-# * check auth-mode=http + fix doc (eg require use-google-auth = False)
-
-class GAEConfiguration(ServerConfiguration, WebConfiguration):
- """repository and web instance in Google AppEngine environment"""
- name = 'app'
- repo_method = 'inmemory'
- options = merge_options((
- ('included-cubes',
- {'type' : 'csv',
- 'default': [],
- 'help': 'list of db model based cubes used by the instance.',
- 'group': 'main', 'level': 1,
- }),
- ('included-yams-cubes',
- {'type' : 'csv',
- 'default': [],
- 'help': 'list of yams based cubes used by the instance.',
- 'group': 'main', 'level': 1,
- }),
- ('use-google-auth',
- {'type' : 'yn',
- 'default': True,
- 'help': 'does this instance rely on google authentication service or not.',
- 'group': 'main', 'level': 1,
- }),
- ('schema-type',
- {'type' : 'choice', 'choices': ('yams', 'dbmodel'),
- 'default': 'yams',
- 'help': 'does this instance is defining its schema using yams or db model.',
- 'group': 'main', 'level': 1,
- }),
- # overriden options
- ('query-log-file',
- {'type' : 'string',
- 'default': None,
- 'help': 'web instance query log file: DON\'T SET A VALUE HERE WHEN '
- 'UPLOADING YOUR INSTANCE. This should only be used to analyse '
- 'queries issued by your instance in the development environment.',
- 'group': 'main', 'level': 2,
- }),
- ('anonymous-user',
- {'type' : 'string',
- 'default': None,
- 'help': 'login of the CubicWeb user account to use for anonymous user '
- '(if you want to allow anonymous). This option will be ignored if '
- 'use-google-auth option is set (in which case you should control '
- 'anonymous access using the app.yaml file)',
- 'group': 'main', 'level': 1,
- }),
-
- ) + WebConfiguration.options + ServerConfiguration.options)
- options = [(optname, optdict) for optname, optdict in options
- if not optname in UNSUPPORTED_OPTIONS]
-
- cubicweb_appobject_path = WebConfiguration.cubicweb_appobject_path | ServerConfiguration.cubicweb_appobject_path
- cubicweb_appobject_path = list(cubicweb_appobject_path) + ['goa/appobjects']
- cube_appobject_path = WebConfiguration.cube_appobject_path | ServerConfiguration.cube_appobject_path
-
- # use file system schema
- read_instance_schema = False
- # schema is not persistent, don't load schema hooks (unavailable)
- schema_hooks = False
- # no user workflow for now
- consider_user_state = False
-
- # deactivate some hooks during [pre|post]create scripts execution
- # (unique values check, owned_by/created_by relations setup)
- free_wheel = True
-
- if not os.environ.get('APYCOT_ROOT'):
- CUBES_DIR = join(CW_SOFTWARE_ROOT, '../cubes')
-
- def __init__(self, appid, apphome=None):
- if apphome is None:
- apphome = 'data'
- self._apphome = apphome
- self._base_url = None
- CubicWebConfiguration.__init__(self, appid)
-
- def __getitem__(self, key):
- if key == 'connections-pool-size':
- return 4 # > 1 to allow multiple user sessions in tests
- if key == 'base-url':
- return self._base_url
- return super(GAEConfiguration, self).__getitem__(key)
-
- # overriden from cubicweb base configuration
-
- @property
- def apphome(self):
- return self._apphome
-
- def cubes(self):
- """return the list of top level cubes used by this instance (eg
- without dependencies)
- """
- if self._cubes is None:
- cubes = self['included-cubes'] + self['included-yams-cubes']
- cubes = self.expand_cubes(cubes)
- return self.reorder_cubes(cubes)
- return self._cubes
-
- def vc_config(self):
- """return CubicWeb's engine and instance's cube versions number"""
- return {}
-
- # overriden from cubicweb web configuration
-
- def instance_md5_version(self):
- return ''
-
- def _init_base_url(self):
- pass
-
- # overriden from cubicweb server configuration
-
- def sources(self):
- return {'system': {'adapter': 'gae'}}
-
- def load_schema(self, schemaclasses=None, extrahook=None):
- try:
- return self._schema
- except AttributeError:
- self._schema = load_schema(self, schemaclasses, extrahook)
- return self._schema
-
- # goa specific
- def repo_session(self, sessionid):
- return self.repository()._sessions[sessionid]
-
- def is_anonymous_user(self, login):
- if self['use-google-auth']:
- from google.appengine.api import users
- return users.get_current_user() is None
- else:
- return login == self.anonymous_user()[0]
-
--- a/goa/goactl.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,252 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""cubicweb on appengine plugins for cubicweb-ctl"""
-
-__docformat__ = "restructuredtext en"
-
-from os.path import exists, join, split, basename, normpath, abspath
-
-from cubicweb import CW_SOFTWARE_ROOT, BadCommandUsage
-from cubicweb.cwctl import CWCTL
-from cubicweb.toolsutils import (Command, copy_skeleton, create_symlink,
- create_dir)
-from cubicweb.cwconfig import CubicWebConfiguration
-
-
-def slink_directories():
- import rql, yams, yapps, docutils, roman
- try:
- import json as simplejson
- except ImportError:
- import simplejson
- from logilab import common as lgc
- from logilab import constraint as lgcstr
- from logilab import mtconverter as lgmtc
- dirs = [
- (lgc.__path__[0], 'logilab/common'),
- (lgmtc.__path__[0], 'logilab/mtconverter'),
- (lgcstr.__path__[0], 'logilab/constraint'),
- (rql.__path__[0], 'rql'),
- (simplejson.__path__[0], 'simplejson'),
- (yams.__path__[0], 'yams'),
- (yapps.__path__[0], 'yapps'),
- (docutils.__path__[0], 'docutils'),
- (roman.__file__.replace('.pyc', '.py'), 'roman.py'),
-
- ('/usr/share/fckeditor/', 'fckeditor'),
-
- (join(CW_SOFTWARE_ROOT, 'web', 'data'), join('cubes', 'shared', 'data')),
- (join(CW_SOFTWARE_ROOT, 'web', 'wdoc'), join('cubes', 'shared', 'wdoc')),
- (join(CW_SOFTWARE_ROOT, 'i18n'), join('cubes', 'shared', 'i18n')),
- (join(CW_SOFTWARE_ROOT, 'goa', 'tools'), 'tools'),
- (join(CW_SOFTWARE_ROOT, 'goa', 'bin'), 'bin'),
- ]
-
- try:
- import dateutil
- import vobject
- dirs.extend([ (dateutil.__path__[0], 'dateutil'),
- (vobject.__path__[0], 'vobject') ] )
- except ImportError:
- pass
- return dirs
-
-COPY_CW_FILES = (
- '__init__.py',
- '__pkginfo__.py',
- '_exceptions.py',
- 'appobject.py',
- 'dbapi.py',
- 'cwvreg.py',
- 'cwconfig.py',
- 'entity.py',
- 'interfaces.py',
- 'i18n.py',
- 'mail.py',
- 'migration.py',
- 'mixins.py',
- 'mttransforms.py',
- 'rqlrewrite.py',
- 'rset.py',
- 'schema.py',
- 'schemaviewer.py',
- 'selectors.py',
- 'uilib.py',
- 'utils.py',
- 'vregistry.py',
- 'view.py',
-
- 'ext/html4zope.py',
- 'ext/rest.py',
-
- 'server/hookhelper.py',
- 'server/hooksmanager.py',
- 'server/hooks.py',
- 'server/migractions.py',
- 'server/pool.py',
- 'server/querier.py',
- 'server/repository.py',
- 'server/securityhooks.py',
- 'server/session.py',
- 'server/serverconfig.py',
- 'server/ssplanner.py',
- 'server/utils.py',
- 'server/sources/__init__.py',
-
- 'entities/__init__.py',
- 'entities/authobjs.py',
- 'entities/lib.py',
- 'entities/schemaobjs.py',
- 'entities/wfobjs.py',
-
- 'sobjects/__init__.py',
- 'sobjects/notification.py',
-
-# XXX would be necessary for goa.testlib but require more stuff to be added
-# such as server.serverconfig and so on (check devtools.__init__)
-# 'devtools/__init__.py',
-# 'devtools/fake.py',
-
- 'web/__init__.py',
- 'web/_exceptions.py',
- 'web/action.py',
- 'web/application.py',
- 'web/box.py',
- 'web/component.py',
- 'web/controller.py',
- 'web/form.py',
- 'web/htmlwidgets.py',
- 'web/httpcache.py',
- 'web/request.py',
- 'web/webconfig.py',
-
- 'web/views/__init__.py',
- 'web/views/actions.py',
- 'web/views/basecomponents.py',
- 'web/views/basecontrollers.py',
- 'web/views/baseforms.py',
- 'web/views/basetemplates.py',
- 'web/views/baseviews.py',
- 'web/views/boxes.py',
- 'web/views/calendar.py',
- 'web/views/error.py',
- 'web/views/editcontroller.py',
- 'web/views/ibreadcrumbs.py',
- 'web/views/idownloadable.py',
- 'web/views/magicsearch.py',
- 'web/views/management.py',
- 'web/views/navigation.py',
- 'web/views/startup.py',
- 'web/views/vcard.py',
- 'web/views/wdoc.py',
- 'web/views/urlpublishing.py',
- 'web/views/urlrewrite.py',
- 'web/views/xbel.py',
-
- 'wsgi/__init__.py',
- 'wsgi/handler.py',
- 'wsgi/request.py',
-
- 'goa/__init__.py',
- 'goa/db.py',
- 'goa/dbinit.py',
- 'goa/dbmyams.py',
- 'goa/goaconfig.py',
- 'goa/goavreg.py',
- 'goa/gaesource.py',
- 'goa/rqlinterpreter.py',
- 'goa/appobjects/__init__.py',
- 'goa/appobjects/components.py',
- 'goa/appobjects/dbmgmt.py',
- 'goa/appobjects/gauthservice.py',
- 'goa/appobjects/sessions.py',
-
- 'schemas/bootstrap.py',
- 'schemas/base.py',
- )
-
-OVERRIDEN_FILES = (
- ('toolsutils.py', 'toolsutils.py'),
- ('mttransforms.py', 'mttransforms.py'),
- ('server__init__.py', 'server/__init__.py'),
- ('rqlannotation.py', 'server/rqlannotation.py'),
- )
-
-
-def create_init_file(pkgdir, pkgname):
- open(join(pkgdir, '__init__.py'), 'w').write('"""%s pkg"""' % pkgname)
-
-
-class NewGoogleAppCommand(Command):
- """Create a new google appengine instance.
-
- <instance directory>
- the path to the appengine instance directory
- """
- name = 'newgapp'
- arguments = '<instance directory>'
-
- def run(self, args):
- if len(args) != 1:
- raise BadCommandUsage("exactly one argument is expected")
- appldir, = args
- appldir = normpath(abspath(appldir))
- appid = basename(appldir)
- context = {'appname': appid}
- # goa instance'skeleton
- copy_skeleton(join(CW_SOFTWARE_ROOT, 'goa', 'skel'),
- appldir, context, askconfirm=True)
- # cubicweb core dependencies
- for directory, subdirectory in slink_directories():
- subdirectory = join(appldir, subdirectory)
- if not exists(split(subdirectory)[0]):
- create_dir(split(subdirectory)[0])
- create_symlink(directory, join(appldir, subdirectory))
- create_init_file(join(appldir, 'logilab'), 'logilab')
- # copy supported part of cubicweb
- create_dir(join(appldir, 'cubicweb'))
- for fpath in COPY_CW_FILES:
- target = join(appldir, 'cubicweb', fpath)
- if not exists(split(target)[0]):
- create_dir(split(target)[0])
- create_symlink(join(CW_SOFTWARE_ROOT, fpath), target)
- # overriden files
- for fpath, subfpath in OVERRIDEN_FILES:
- create_symlink(join(CW_SOFTWARE_ROOT, 'goa', 'overrides', fpath),
- join(appldir, 'cubicweb', subfpath))
- # link every supported components
- packagesdir = join(appldir, 'cubes')
- create_init_file(join(appldir, 'cubes'), 'cubes')
- for include in ('addressbook','basket', 'blog','folder',
- 'tag', 'comment', 'file', 'link',
- 'mailinglist', 'person', 'task', 'zone',
- ):
- create_symlink(CubicWebConfiguration.cube_dir(include),
- join(packagesdir, include))
- # generate sample config
- from cubicweb.goa.goaconfig import GAEConfiguration
- from cubicweb.migration import MigrationHelper
- config = GAEConfiguration(appid, appldir)
- if exists(config.main_config_file()):
- mih = MigrationHelper(config)
- mih.rewrite_configuration()
- else:
- config.save()
-
-
-CWCTL.register(NewGoogleAppCommand)
--- a/goa/goavreg.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""goa specific registry
-
-"""
-__docformat__ = "restructuredtext en"
-
-from os import listdir
-from os.path import join, isdir
-
-from cubicweb import CW_SOFTWARE_ROOT
-from cubicweb.cwvreg import CubicWebVRegistry
-
-
-def _pkg_name(cube, module):
- if cube is None:
- return module
- return 'cubes.%s.%s' % (cube, module)
-
-class GAEVRegistry(CubicWebVRegistry):
-
- def set_schema(self, schema):
- """disable reload hooks of cubicweb registry set_schema method"""
- self.schema = schema
-
- def load(self, applroot):
- from cubicweb.goa import db
- self.load_module(db) # AnyEntity class
- # explicit loading, we don't want to load __init__.py
- self.load_directory(join(CW_SOFTWARE_ROOT, 'entities'),
- 'cubicweb.entities', skip=('__init__.py',))
- self.load_directory(join(CW_SOFTWARE_ROOT, 'web', 'views'),
- 'cubicweb.web.views')
- self.load_directory(join(CW_SOFTWARE_ROOT, 'goa', 'appobjects'),
- 'cubicweb.goa.appobjects')
- for cube in reversed(self.config.cubes()):
- self.load_cube(cube)
- self.load_instance(applroot)
-
- def load_directory(self, directory, cube, skip=()):
- for filename in listdir(directory):
- if filename[-3:] == '.py' and not filename in skip:
- self._import('%s.%s' % (cube, filename[:-3]))
-
- def load_cube(self, cube):
- self._auto_load(self.config.cube_dir(cube),
- cube in self.config['included-cubes'],
- cube)
-
- def load_instance(self, applroot):
- self._auto_load(applroot, self.config['schema-type'] == 'dbmodel')
-
- def _import(self, modname):
- obj = __import__(modname)
- for attr in modname.split('.')[1:]:
- obj = getattr(obj, attr)
- self.load_module(obj)
-
- def _auto_load(self, path, loadschema, cube=None):
- vobjpath = self.config.cube_appobject_path
- for filename in listdir(path):
- if filename[-3:] == '.py' and filename[:-3] in vobjpath:
- self._import(_pkg_name(cube, filename[:-3]))
- else:
- abspath = join(path, filename)
- if isdir(abspath) and filename in vobjpath:
- self.load_directory(abspath, _pkg_name(cube, filename))
- if loadschema:
- # when using db.Model defined schema, the defined class is used as
- # entity class as well and so have to be registered
- self._import(_pkg_name(cube, 'schema'))
--- a/goa/overrides/__init__.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-# server.__init__
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
--- a/goa/overrides/mttransforms.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""mime type transformation engine for cubicweb, based on mtconverter
-
-"""
-__docformat__ = "restructuredtext en"
-
-from logilab import mtconverter
-
-from logilab.mtconverter.engine import TransformEngine
-from logilab.mtconverter.transform import Transform
-from cubicweb.uilib import rest_publish, html_publish, remove_html_tags
-
-HTML_MIMETYPES = ('text/html', 'text/xhtml', 'application/xhtml+xml')
-# CubicWeb specific transformations
-
-class rest_to_html(Transform):
- inputs = ('text/rest', 'text/x-rst')
- output = 'text/html'
- def _convert(self, trdata):
- return rest_publish(trdata.appobject, trdata.decode())
-
-class html_to_html(Transform):
- inputs = HTML_MIMETYPES
- output = 'text/html'
- def _convert(self, trdata):
- return html_publish(trdata.appobject, trdata.data)
-
-
-# Instantiate and configure the transformation engine
-
-mtconverter.UNICODE_POLICY = 'replace'
-
-ENGINE = TransformEngine()
-ENGINE.add_transform(rest_to_html())
-ENGINE.add_transform(html_to_html())
-
-HAS_PIL_TRANSFORMS = False
-HAS_PYGMENTS_TRANSFORMS = False
-
-class html_to_text(Transform):
- inputs = HTML_MIMETYPES
- output = 'text/plain'
- def _convert(self, trdata):
- return remove_html_tags(trdata.data)
-ENGINE.add_transform(html_to_text())
--- a/goa/overrides/rqlannotation.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-"""
-__docformat__ = "restructuredtext en"
-
-def set_qdata(getrschema, union, noinvariant):
- pass
-
-class SQLGenAnnotator(object):
- def __init__(self, schema):
- self.schema = schema
- self.nfdomain = frozenset(eschema.type for eschema in schema.entities()
- if not eschema.final)
- def annotate(self, rqlst):
- rqlst.has_text_query = False
- rqlst.need_distinct = False
-
-
--- a/goa/overrides/server__init__.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-# server debugging flag
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-DEBUG = False
-
-# sqlite'stored procedures have to be registered at connexion opening time
-SQL_CONNECT_HOOKS = {}
-
-# add to this set relations which should have their add security checking done
-# *BEFORE* adding the actual relation (done after by default)
-BEFORE_ADD_RELATIONS = set(('owned_by',))
-
-# add to this set relations which should have their add security checking done
-# *at COMMIT TIME* (done after by default)
-ON_COMMIT_ADD_RELATIONS = set(())
-
-# available sources registry
-SOURCE_TYPES = {}
--- a/goa/overrides/server_utils.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-
-class RepoThread(object):
- def __init__(self, *args):
- pass # XXX raise
- def start(self):
- pass
- def join(self):
- pass
-
-class LoopTask(RepoThread):
- def cancel(self):
- pass
--- a/goa/overrides/toolsutils.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-import sys
-from cubicweb import warning
-
-def lines(path, comments=None):
- result = []
- for line in open(path, 'U'):
- line = line.strip()
- if line and (comments is None or not line.startswith(comments)):
- result.append(line)
- return result
-
-def read_config(config_file):
- """read the instance configuration from a file and return it as a
- dictionnary
-
- :type config_file: str
- :param config_file: path to the configuration file
-
- :rtype: dict
- :return: a dictionary with specified values associated to option names
- """
- config = current = {}
- try:
- for line in lines(config_file, comments='#'):
- try:
- option, value = line.split('=', 1)
- except ValueError:
- option = line.strip().lower()
- if option[0] == '[':
- # start a section
- section = option[1:-1]
- assert not config.has_key(section), \
- 'Section %s is defined more than once' % section
- config[section] = current = {}
- continue
- print >> sys.stderr, 'ignoring malformed line\n%r' % line
- continue
- option = option.strip().replace(' ', '_')
- value = value.strip()
- current[option] = value or None
- except IOError, ex:
- warning('missing or non readable configuration file %s (%s)',
- config_file, ex)
- return config
-
-def env_path(env_var, default, name):
- return default
-
-def create_dir(*args):
- raise RuntimeError()
--- a/goa/rqlinterpreter.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,684 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""provide a minimal RQL support for google appengine dbmodel
-
-"""
-__docformat__ = "restructuredtext en"
-
-from datetime import datetime
-
-from rql import RQLHelper, nodes
-
-from cubicweb import Binary
-from cubicweb.rset import ResultSet
-from cubicweb.server import SQL_CONNECT_HOOKS
-
-from google.appengine.api.datastore import Key, Get, Query, Entity
-from google.appengine.api.datastore_types import Text, Blob
-from google.appengine.api.datastore_errors import EntityNotFoundError, BadKeyError
-
-
-def etype_from_key(key):
- return Key(key).kind()
-
-def poss_var_types(myvar, ovar, kind, solutions):
- return frozenset(etypes[myvar] for etypes in solutions
- if etypes[ovar] == kind)
-
-def expand_result(results, result, myvar, values, dsget=None):
- values = map(dsget, values)
- if values:
- result[myvar] = values.pop(0)
- for value in values:
- newresult = result.copy()
- newresult[myvar] = value
- results.append(newresult)
- else:
- results.remove(result)
-
-def _resolve(restrictions, solutions, fixed):
- varname = restrictions[0].searched_var
- objs = []
- for etype in frozenset(etypes[varname] for etypes in solutions):
- gqlargs = {}
- query = Query(etype)
- for restriction in restrictions:
- restriction.fill_query(fixed, query)
- pobjs = query.Run()
- if varname in fixed:
- value = fixed[varname]
- objs += (x for x in pobjs if x == value)
- else:
- objs += pobjs
- if varname in fixed and not objs:
- raise EidMismatch(varname, value)
- return objs
-
-def _resolve_not(restrictions, solutions, fixed):
- restr = restrictions[0]
- constrvarname = restr.constraint_var
- if len(restrictions) > 1 or not constrvarname in fixed:
- raise NotImplementedError()
- varname = restr.searched_var
- objs = []
- for etype in frozenset(etypes[varname] for etypes in solutions):
- gqlargs = {}
- for operator in ('<', '>'):
- query = Query(etype)
- restr.fill_query(fixed, query, operator)
- objs += query.Run()
- return objs
-
-def _print_results(rlist):
- return '[%s]' % ', '.join(_print_result(r) for r in rlist)
-
-def _print_result(rdict):
- string = []
- for k, v in rdict.iteritems():
- if isinstance(v, Entity):
- string.append('%s: %s' % (k, v.key()))#_print_result(v)))
- elif isinstance(v, list):
- string.append('%s: [%s]' % (k, ', '.join(str(i) for i in v)))
- else:
- string.append('%s: %s' % (k, v))
- return '{%s}' % ', '.join(string)
-
-
-class EidMismatch(Exception):
- def __init__(self, varname, value):
- self.varname = varname
- self.value = value
-
-
-class Restriction(object):
- supported_operators = ('=',)
- def __init__(self, rel):
- operator = rel.children[1].operator
- if not operator in self.supported_operators:
- raise NotImplementedError('unsupported operator')
- self.rel = rel
- self.operator = operator
- self.rtype = rel.r_type
- self.var = rel.children[0]
-
- def __repr__(self):
- return '<%s for %s>' % (self.__class__.__name__, self.rel)
-
- @property
- def rhs(self):
- return self.rel.children[1].children[0]
-
-
-class MultipleRestriction(object):
- def __init__(self, restrictions):
- self.restrictions = restrictions
-
- def resolve(self, solutions, fixed):
- return _resolve(self.restrictions, solutions, fixed)
-
-
-class VariableSelection(Restriction):
- def __init__(self, rel, dsget, prefix='s'):
- Restriction.__init__(self, rel)
- self._dsget = dsget
- self._not = self.rel.neged(strict=True)
- self._prefix = prefix + '_'
-
- def __repr__(self):
- return '<%s%s for %s>' % (self._prefix[0], self.__class__.__name__, self.rel)
-
- @property
- def searched_var(self):
- if self._prefix == 's_':
- return self.var.name
- return self.rhs.name
-
- @property
- def constraint_var(self):
- if self._prefix == 's_':
- return self.rhs.name
- return self.var.name
-
- def _possible_values(self, myvar, ovar, entity, solutions, dsprefix):
- if self.rtype == 'identity':
- return (entity.key(),)
- value = entity.get(dsprefix + self.rtype)
- if value is None:
- return []
- if not isinstance(value, list):
- value = [value]
- vartypes = poss_var_types(myvar, ovar, entity.kind(), solutions)
- return (v for v in value if v.kind() in vartypes)
-
- def complete_and_filter(self, solutions, results):
- myvar = self.rhs.name
- ovar = self.var.name
- rtype = self.rtype
- if self.schema.rschema(rtype).final:
- # should be detected by rql.stcheck: "Any C WHERE NOT X attr C" doesn't make sense
- #if self._not:
- # raise NotImplementedError()
- for result in results:
- result[myvar] = result[ovar].get('s_'+rtype)
- elif self.var.name in results[0]:
- if self.rhs.name in results[0]:
- self.filter(solutions, results)
- else:
- if self._not:
- raise NotImplementedError()
- for result in results[:]:
- values = self._possible_values(myvar, ovar, result[ovar],
- solutions, 's_')
- expand_result(results, result, myvar, values, self._dsget)
- else:
- assert self.rhs.name in results[0]
- self.object_complete_and_filter(solutions, results)
-
- def filter(self, solutions, results):
- myvar = self.rhs.name
- ovar = self.var.name
- newsols = {}
- for result in results[:]:
- entity = result[ovar]
- key = entity.key()
- if not key in newsols:
- values = self._possible_values(myvar, ovar, entity, solutions, 's_')
- newsols[key] = frozenset(v for v in values)
- if self._not:
- if result[myvar].key() in newsols[key]:
- results.remove(result)
- elif not result[myvar].key() in newsols[key]:
- results.remove(result)
-
- def object_complete_and_filter(self, solutions, results):
- if self._not:
- raise NotImplementedError()
- myvar = self.var.name
- ovar = self.rhs.name
- for result in results[:]:
- values = self._possible_values(myvar, ovar, result[ovar],
- solutions, 'o_')
- expand_result(results, result, myvar, values, self._dsget)
-
-
-class EidRestriction(Restriction):
- def __init__(self, rel, dsget):
- Restriction.__init__(self, rel)
- self._dsget = dsget
-
- def resolve(self, kwargs):
- value = self.rel.children[1].children[0].eval(kwargs)
- return self._dsget(value)
-
-
-class RelationRestriction(VariableSelection):
-
- def _get_value(self, fixed):
- return fixed[self.constraint_var].key()
-
- def fill_query(self, fixed, query, operator=None):
- restr = '%s%s %s' % (self._prefix, self.rtype, operator or self.operator)
- query[restr] = self._get_value(fixed)
-
- def resolve(self, solutions, fixed):
- if self.rtype == 'identity':
- if self._not:
- raise NotImplementedError()
- return [fixed[self.constraint_var]]
- if self._not:
- return _resolve_not([self], solutions, fixed)
- return _resolve([self], solutions, fixed)
-
-
-class NotRelationRestriction(RelationRestriction):
-
- def _get_value(self, fixed):
- return None
-
- def resolve(self, solutions, fixed):
- if self.rtype == 'identity':
- raise NotImplementedError()
- return _resolve([self], solutions, fixed)
-
-
-class AttributeRestriction(RelationRestriction):
- supported_operators = ('=', '>', '>=', '<', '<=', 'ILIKE')
- def __init__(self, rel, kwargs):
- RelationRestriction.__init__(self, rel, None)
- value = self.rhs.eval(kwargs)
- self.value = value
- if self.operator == 'ILIKE':
- if value.startswith('%'):
- raise NotImplementedError('LIKE is only supported for prefix search')
- if not value.endswith('%'):
- raise NotImplementedError('LIKE is only supported for prefix search')
- self.operator = '>'
- self.value = value[:-1]
-
- def complete_and_filter(self, solutions, results):
- # check lhs var first in case this is a restriction
- assert self._not
- myvar, rtype, value = self.var.name, self.rtype, self.value
- for result in results[:]:
- if result[myvar].get('s_'+rtype) == value:
- results.remove(result)
-
- def _get_value(self, fixed):
- return self.value
-
-
-class DateAttributeRestriction(AttributeRestriction):
- """just a thin layer on top af `AttributeRestriction` that
- tries to convert date strings such as in :
- Any X WHERE X creation_date >= '2008-03-04'
- """
- def __init__(self, rel, kwargs):
- super(DateAttributeRestriction, self).__init__(rel, kwargs)
- if isinstance(self.value, basestring):
-# try:
- self.value = datetime.strptime(self.value, '%Y-%m-%d')
-# except Exception, exc:
-# from logging import error
-# error('unable to parse date %s with format %%Y-%%m-%%d (exc=%s)', value, exc)
-
-
-class AttributeInRestriction(AttributeRestriction):
- def __init__(self, rel, kwargs):
- RelationRestriction.__init__(self, rel, None)
- values = []
- for c in self.rel.children[1].iget_nodes(nodes.Constant):
- values.append(c.eval(kwargs))
- self.value = values
-
- @property
- def operator(self):
- return 'in'
-
-
-class TypeRestriction(AttributeRestriction):
- def __init__(self, var):
- self.var = var
-
- def __repr__(self):
- return '<%s for %s>' % (self.__class__.__name__, self.var)
-
- def resolve(self, solutions, fixed):
- objs = []
- for etype in frozenset(etypes[self.var.name] for etypes in solutions):
- objs += Query(etype).Run()
- return objs
-
-
-def append_result(res, descr, i, j, value, etype):
- if value is not None:
- if isinstance(value, Text):
- value = unicode(value)
- elif isinstance(value, Blob):
- value = Binary(str(value))
- if j == 0:
- res.append([value])
- descr.append([etype])
- else:
- res[i].append(value)
- descr[i].append(etype)
-
-
-class ValueResolver(object):
- def __init__(self, functions, args, term):
- self.functions = functions
- self.args = args
- self.term = term
- self._solution = self.term.stmt.solutions[0]
-
- def compute(self, result):
- """return (entity type, value) to which self.term is evaluated according
- to the given result dictionnary and to query arguments (self.args)
- """
- return self.term.accept(self, result)
-
- def visit_function(self, node, result):
- args = tuple(n.accept(self, result)[1] for n in node.children)
- value = self.functions[node.name](*args)
- return node.get_type(self._solution, self.args), value
-
- def visit_variableref(self, node, result):
- value = result[node.name]
- try:
- etype = value.kind()
- value = str(value.key())
- except AttributeError:
- etype = self._solution[node.name]
- return etype, value
-
- def visit_constant(self, node, result):
- return node.get_type(kwargs=self.args), node.eval(self.args)
-
-
-class RQLInterpreter(object):
- """algorithm:
- 1. visit the restriction clauses and collect restriction for each subject
- of a relation. Different restriction types are:
- * EidRestriction
- * AttributeRestriction
- * RelationRestriction
- * VariableSelection (not really a restriction)
- -> dictionary {<variable>: [restriction...], ...}
- 2. resolve eid restrictions
- 3. for each select in union:
- for each solution in select'solutions:
- 1. resolve variables which have attribute restriction
- 2. resolve relation restriction
- 3. resolve selection and add to global results
- """
- def __init__(self, schema):
- self.schema = schema
- Restriction.schema = schema # yalta!
- self.rqlhelper = RQLHelper(schema, {'eid': etype_from_key})
- self._stored_proc = {'LOWER': lambda x: x.lower(),
- 'UPPER': lambda x: x.upper()}
- for cb in SQL_CONNECT_HOOKS.get('sqlite', []):
- cb(self)
-
- # emulate sqlite connection interface so we can reuse stored procedures
- def create_function(self, name, nbargs, func):
- self._stored_proc[name] = func
-
- def create_aggregate(self, name, nbargs, func):
- self._stored_proc[name] = func
-
-
- def execute(self, operation, parameters=None, eid_key=None, build_descr=True):
- rqlst = self.rqlhelper.parse(operation, annotate=True)
- try:
- self.rqlhelper.compute_solutions(rqlst, kwargs=parameters)
- except BadKeyError:
- results, description = [], []
- else:
- results, description = self.interpret(rqlst, parameters)
- return ResultSet(results, operation, parameters, description, rqlst=rqlst)
-
- def interpret(self, node, kwargs, dsget=None):
- if dsget is None:
- self._dsget = Get
- else:
- self._dsget = dsget
- try:
- return node.accept(self, kwargs)
- except NotImplementedError:
- self.critical('support for query not implemented: %s', node)
- raise
-
- def visit_union(self, node, kwargs):
- results, description = [], []
- extra = {'kwargs': kwargs}
- for child in node.children:
- pres, pdescr = self.visit_select(child, extra)
- results += pres
- description += pdescr
- return results, description
-
- def visit_select(self, node, extra):
- constraints = {}
- if node.where is not None:
- node.where.accept(self, constraints, extra)
- fixed, toresolve, postresolve, postfilters = {}, {}, {}, []
- # extract NOT filters
- for vname, restrictions in constraints.items():
- for restr in restrictions[:]:
- if isinstance(restr, AttributeRestriction) and restr._not:
- postfilters.append(restr)
- restrictions.remove(restr)
- if not restrictions:
- del constraints[vname]
- # add TypeRestriction for variable which have no restrictions at all
- for varname, var in node.defined_vars.iteritems():
- if not varname in constraints:
- constraints[varname] = [TypeRestriction(var)]
- #print node, constraints
- # compute eid restrictions
- kwargs = extra['kwargs']
- for varname, restrictions in constraints.iteritems():
- for restr in restrictions[:]:
- if isinstance(restr, EidRestriction):
- assert not varname in fixed
- try:
- value = restr.resolve(kwargs)
- fixed[varname] = value
- except EntityNotFoundError:
- return [], []
- restrictions.remove(restr)
- #print 'fixed', fixed.keys()
- # combine remaining restrictions
- for varname, restrictions in constraints.iteritems():
- for restr in restrictions:
- if isinstance(restr, AttributeRestriction):
- toresolve.setdefault(varname, []).append(restr)
- elif isinstance(restr, NotRelationRestriction) or (
- isinstance(restr, RelationRestriction) and
- not restr.searched_var in fixed and restr.constraint_var in fixed):
- toresolve.setdefault(varname, []).append(restr)
- else:
- postresolve.setdefault(varname, []).append(restr)
- try:
- if len(toresolve[varname]) > 1:
- toresolve[varname] = MultipleRestriction(toresolve[varname])
- else:
- toresolve[varname] = toresolve[varname][0]
- except KeyError:
- pass
- #print 'toresolve %s' % toresolve
- #print 'postresolve %s' % postresolve
- # resolve additional restrictions
- if fixed:
- partres = [fixed.copy()]
- else:
- partres = []
- for varname, restr in toresolve.iteritems():
- varpartres = partres[:]
- try:
- values = tuple(restr.resolve(node.solutions, fixed))
- except EidMismatch, ex:
- varname = ex.varname
- value = ex.value
- partres = [res for res in partres if res[varname] != value]
- if partres:
- continue
- # some join failed, no possible results
- return [], []
- if not values:
- # some join failed, no possible results
- return [], []
- if not varpartres:
- # init results
- for value in values:
- partres.append({varname: value})
- elif not varname in partres[0]:
- # cartesian product
- for res in partres:
- res[varname] = values[0]
- for res in partres[:]:
- for value in values[1:]:
- res = res.copy()
- res[varname] = value
- partres.append(res)
- else:
- # union
- for res in varpartres:
- for value in values:
- res = res.copy()
- res[varname] = value
- partres.append(res)
- #print 'partres', len(partres)
- #print partres
- # Note: don't check for empty partres since constant selection may still
- # produce result at this point
- # sort to get RelationRestriction before AttributeSelection
- restrictions = sorted((restr for restrictions in postresolve.itervalues()
- for restr in restrictions),
- key=lambda x: not isinstance(x, RelationRestriction))
- # compute stuff not doable in the previous step using datastore queries
- for restr in restrictions + postfilters:
- restr.complete_and_filter(node.solutions, partres)
- if not partres:
- # some join failed, no possible results
- return [], []
- if extra.pop('has_exists', False):
- # remove potential duplicates introduced by exists
- toremovevars = [v.name for v in node.defined_vars.itervalues()
- if not v.scope is node]
- if toremovevars:
- newpartres = []
- for result in partres:
- for var in toremovevars:
- del result[var]
- if not result in newpartres:
- newpartres.append(result)
- if not newpartres:
- # some join failed, no possible results
- return [], []
- partres = newpartres
- if node.orderby:
- for sortterm in reversed(node.orderby):
- resolver = ValueResolver(self._stored_proc, kwargs, sortterm.term)
- partres.sort(reverse=not sortterm.asc,
- key=lambda x: resolver.compute(x)[1])
- if partres:
- if node.offset:
- partres = partres[node.offset:]
- if node.limit:
- partres = partres[:node.limit]
- if not partres:
- return [], []
- #print 'completed partres', _print_results(partres)
- # compute results
- res, descr = [], []
- for j, term in enumerate(node.selection):
- resolver = ValueResolver(self._stored_proc, kwargs, term)
- if not partres:
- etype, value = resolver.compute({})
- # only constant selected
- if not res:
- res.append([])
- descr.append([])
- res[0].append(value)
- descr[0].append(etype)
- else:
- for i, sol in enumerate(partres):
- etype, value = resolver.compute(sol)
- append_result(res, descr, i, j, value, etype)
- #print '--------->', res
- return res, descr
-
- def visit_and(self, node, constraints, extra):
- for child in node.children:
- child.accept(self, constraints, extra)
- def visit_exists(self, node, constraints, extra):
- extra['has_exists'] = True
- self.visit_and(node, constraints, extra)
-
- def visit_not(self, node, constraints, extra):
- for child in node.children:
- child.accept(self, constraints, extra)
- try:
- extra.pop(node)
- except KeyError:
- raise NotImplementedError()
-
- def visit_relation(self, node, constraints, extra):
- if node.is_types_restriction():
- return
- rschema = self.schema.rschema(node.r_type)
- neged = node.neged(strict=True)
- if neged:
- # ok, we *may* process this Not node (not implemented error will be
- # raised later if we can't)
- extra[node.parent] = True
- if rschema.final:
- self._visit_final_relation(rschema, node, constraints, extra)
- elif neged:
- self._visit_non_final_neged_relation(rschema, node, constraints)
- else:
- self._visit_non_final_relation(rschema, node, constraints)
-
- def _visit_non_final_relation(self, rschema, node, constraints, not_=False):
- lhs, rhs = node.get_variable_parts()
- for v1, v2, prefix in ((lhs, rhs, 's'), (rhs, lhs, 'o')):
- #if not_:
- nbrels = len(v2.variable.stinfo['relations'])
- #else:
- # nbrels = len(v2.variable.stinfo['relations']) - len(v2.variable.stinfo['uidrels'])
- if nbrels > 1:
- constraints.setdefault(v1.name, []).append(
- RelationRestriction(node, self._dsget, prefix))
- # just init an empty list for v2 variable to avoid a
- # TypeRestriction being added for it
- constraints.setdefault(v2.name, [])
- break
- else:
- constraints.setdefault(rhs.name, []).append(
- VariableSelection(node, self._dsget, 's'))
-
- def _visit_non_final_neged_relation(self, rschema, node, constraints):
- lhs, rhs = node.get_variable_parts()
- for v1, v2, prefix in ((lhs, rhs, 's'), (rhs, lhs, 'o')):
- stinfo = v2.variable.stinfo
- if not stinfo['selected'] and len(stinfo['relations']) == 1:
- constraints.setdefault(v1.name, []).append(
- NotRelationRestriction(node, self._dsget, prefix))
- constraints.setdefault(v2.name, [])
- break
- else:
- self._visit_non_final_relation(rschema, node, constraints, True)
-
- def _visit_final_relation(self, rschema, node, constraints, extra):
- varname = node.children[0].name
- if rschema.type == 'eid':
- constraints.setdefault(varname, []).append(
- EidRestriction(node, self._dsget))
- else:
- rhs = node.children[1].children[0]
- if isinstance(rhs, nodes.VariableRef):
- constraints.setdefault(rhs.name, []).append(
- VariableSelection(node, self._dsget))
- elif isinstance(rhs, nodes.Constant):
- if rschema.objects()[0] in ('Datetime', 'Date'): # XXX
- constraints.setdefault(varname, []).append(
- DateAttributeRestriction(node, extra['kwargs']))
- else:
- constraints.setdefault(varname, []).append(
- AttributeRestriction(node, extra['kwargs']))
- elif isinstance(rhs, nodes.Function) and rhs.name == 'IN':
- constraints.setdefault(varname, []).append(
- AttributeInRestriction(node, extra['kwargs']))
- else:
- raise NotImplementedError()
-
- def _not_implemented(self, *args, **kwargs):
- raise NotImplementedError()
-
- visit_or = _not_implemented
- # shouldn't occurs
- visit_set = _not_implemented
- visit_insert = _not_implemented
- visit_delete = _not_implemented
-
-
-from logging import getLogger
-from cubicweb import set_log_methods
-set_log_methods(RQLInterpreter, getLogger('cubicweb.goa.rqlinterpreter'))
-set_log_methods(Restriction, getLogger('cubicweb.goa.rqlinterpreter'))
--- a/goa/skel/app.yaml.tmpl Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-application: %(appname)s
-version: 0-1
-runtime: python
-api_version: 1
-
-handlers:
-- url: /admin/.*
- script: $PYTHON_LIB/google/appengine/ext/admin
- login: admin
-- url: /data
- static_dir: cubes/shared/data
-- url: /fckeditor
- static_dir: fckeditor
-- url: /_load
- script: loader.py
- login: admin
-- url: .*
- script: main.py
- # comment the line below to allow anonymous access or if you don't want to use
- # google authentication service
- login: required
-
-skip_files: |
- ^(.*/)?(
- (app\.yaml)|
- (app\.yml)|
- (index\.yaml)|
- (index\.yml)|
- (#.*#)|
- (.*~)|
- (.*\.py[co])|
- (.*\.xcf)|
- (.*\.asp)|
- (.*\.aspx)|
- (.*\.cfm)|
- (.*\.po)|
- (.*/RCS/.*)|
- (\..*)|
- (.*ChangeLog)|
- (.*README)|
- (.*TODO)|
- (.*DEPENDS)|
- (.*MANIFEST)|
- (.*MANIFEST.in)|
- (.*setup\.py)|
- (.*,cover)|
- (.*\.orig)|
- (.*/test/.*)|
- (.*/tests/.*)|
- (.*/bin/.*)|
- (.*/build/.*)|
- (.*/debian/.*)|
- (.*/doc/.*)|
- (.*/skins/office2003/.*)|
- (.*/editor/skins/silver/.*)|
- (.*/editor/filemanager/.*)|
- (.*/editor/plugins/.*)|
- (.*/editor/images/smiley/.*)|
- (.*/editor/.*spellerpages.*)|
- (.*/docutils/writers/s5_html/.*)|
- (.*/docutils/writers/latex2e/.*)|
- (.*/docutils/writers/newlatex2e/.*)|
- (.*/docutils/writers/pep_html/.*)|
- (bin/.*)|
- (tools/.*)|
- (cubicweb.*/data/.*\.js)|
- (cubicweb.*/data/.*\.css)|
- (cubicweb.*/data/.*\.png)|
- (cubicweb.*/data/.*\.gif)|
- (cubicweb.*/data/.*\.gif)|
- )$
-
--- a/goa/skel/custom.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-def postinit(vreg):
- """this callback is called at the end of initialization process
- and can be used to load explicit modules (views or entities).
-
- For instance :
- import someviews
- vreg.load_module(someviws)
- """
- # from migration import migrate
- # migrate(vreg)
--- a/goa/skel/cw-cubes/README.txt Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-This directory is where you should put your lax components.
-
-For your application to actually use a component, you also
-have to modify the ``INCLUDED_COMPONENTS`` variable in
-the ``custom.py`` module.
-
-
--- a/goa/skel/i18n/en.po Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-# LAX application po file
-
-msgid ""
-msgstr ""
-"Project-Id-Version: erudi 2.48.2\n"
-"PO-Revision-Date: 2008-03-28 18:14+0100\n"
-"Last-Translator: Logilab Team <contact@logilab.fr>\n"
-"Language-Team: fr <contact@logilab.fr>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: ginco-devtools\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
--- a/goa/skel/i18n/fr.po Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-# LAX application po file
-
-msgid ""
-msgstr ""
-"Project-Id-Version: erudi 2.48.2\n"
-"PO-Revision-Date: 2008-03-28 18:14+0100\n"
-"Last-Translator: Logilab Team <contact@logilab.fr>\n"
-"Language-Team: fr <contact@logilab.fr>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: ginco-devtools\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-
--- a/goa/skel/loader.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-if __name__ == '__main__':
-
- from os.path import dirname, abspath
- from cubicweb import goa
- from cubicweb.goa.goaconfig import GAEConfiguration
- from cubicweb.goa.dbinit import create_user, create_groups
-
- # compute instance's root directory
- APPLROOT = dirname(abspath(__file__))
- # apply monkey patches first
- goa.do_monkey_patch()
- # get instance's configuration (will be loaded from app.conf file)
- GAEConfiguration.uiprops['JAVASCRIPTS'].append('DATADIR/goa.js')
- config = GAEConfiguration('toto', APPLROOT)
- # create default groups
- create_groups()
- if not config['use-google-auth']:
- # create default admin
- create_user('admin', 'admin', ('managers', 'users'))
- # create anonymous user if specified
- anonlogin = config['anonymous-user']
- if anonlogin:
- create_user(anonlogin, config['anonymous-password'], ('guests',))
- print 'content initialized'
--- a/goa/skel/main.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""module defining the root handler for a lax instance. You should not have
-to change anything here.
-
-"""
-__docformat__ = "restructuredtext en"
-
-# compute instance's root directory
-from os.path import dirname, abspath
-APPLROOT = dirname(abspath(__file__))
-
-# apply monkey patches first
-from cubicweb import goa
-goa.do_monkey_patch()
-
-# get instance's configuration (will be loaded from app.conf file)
-from cubicweb.goa.goaconfig import GAEConfiguration
-GAEConfiguration.uiprops['JAVASCRIPTS'].append('DATADIR/goa.js')
-config = GAEConfiguration('toto', APPLROOT)
-
-# dynamic objects registry
-from cubicweb.goa.goavreg import GAEVregistry
-vreg = GAEVregistry(config, debug=goa.MODE == 'dev')
-
-# trigger automatic classes registration (metaclass magic), should be done
-# before schema loading
-import custom
-
-# load instance'schema
-vreg.schema = config.load_schema()
-
-# load dynamic objects
-vreg.load(APPLROOT)
-
-# call the postinit so custom get a chance to do instance specific stuff
-custom.postinit(vreg)
-
-from cubicweb.wsgi.handler import CubicWebWSGIApplication
-application = CubicWebWSGIApplication(config, vreg=vreg)
-
-# main function so this handler module is cached
-def main():
- from wsgiref.handlers import CGIHandler
- CGIHandler().run(application)
-
-if __name__ == "__main__":
- main()
--- a/goa/skel/schema.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-
-class Blog(EntityType):
- title = String(maxsize=50, required=True)
- description = String()
-
-class BlogEntry(EntityType):
- title = String(maxsize=100, required=True)
- publish_date = Date(default='TODAY')
- text = RichString(fulltextindexed=True)
- category = String(vocabulary=('important','business'))
- entry_of = SubjectRelation('Blog', cardinality='?*')
--- a/goa/skel/views.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-# custom application views
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-from datetime import date
-
-from logilab.common.date import last_day
-
-from cubicweb.web.views import baseviews, boxes, calendar
-from cubicweb.web.htmlwidgets import BoxLink, BoxWidget
-
-_ = unicode
-
-
-class BlogEntryPrimaryView(baseviews.PrimaryView):
- accepts = ('BlogEntry',)
-
- def cell_call(self, row, col):
- entity = self.rset.get_entity(row, col)
- self.w(u'<h1>%s</h1>' % entity.dc_title())
- entity.view('metadata', w=self.w)
- self.w(entity.printable_value('text'))
-
-
-class BlogArchiveBox(boxes.BoxTemplate):
- """side box usually displaying some related entities in a primary view"""
- id = 'blog_archives_box'
- title = _('blog archives')
-
- def call(self, **kwargs):
- """display a list of entities by calling their <item_vid> view
- """
- _ = self.req._
- rset = self.req.execute('Any CD ORDERBY CD DESC WHERE B is Blog, B creation_date CD')
- blogmonths = []
- for (blogdate,) in rset:
- year, month = blogdate.year, blogdate.month
- if (year, month) not in blogmonths:
- blogmonths.append( (year, month) )
- box = BoxWidget(_('Blog archives'), id=self.id)
- for year, month in blogmonths:
- firstday = date(year, month, 1)
- lastday = last_day(firstday)
- rql = ('Any B WHERE B is BlogEntry, B creation_date >= "%s", B creation_date <= "%s"'
- % (firstday.strftime('%Y-%m-%d'), lastday.strftime('%Y-%m-%d')))
- url = self.build_url(rql=rql)
- label = u'%s %s' % (_(calendar.MONTHNAMES[month-1]), year)
- box.append( BoxLink(url, label) )
- box.render(self.w)
-
-
-
-
--- a/goa/test/data/__init__.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""zou
-
-"""
--- a/goa/test/data/schema.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-
-
-class YamsEntity(EntityType):
- if 'Blog' in defined_types and 'Article' in defined_types:
- ambiguous_relation = SubjectRelation(('Blog', 'Article'))
- if 'Blog' in defined_types:
- inlined_relation = SubjectRelation('Blog', cardinality='?*')
-
-class inlined_relation(RelationType):
- inlined = True
-
--- a/goa/test/data/settings.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-TEMPLATE_DEBUG = False
--- a/goa/test/data/views.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-# -*- coding: utf-8 -*-
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-import os
-os.environ["DJANGO_SETTINGS_MODULE"] = 'data.settings'
-
-from django import template
-
-
-def encode_output(self, output):
- # Check type so that we don't run str() on a Unicode object
- if not isinstance(output, basestring):
- return unicode(output)
- return output
-
-template.VariableNode.encode_output = encode_output
-
-from cubicweb.view import StartupView
-
-INDEX_TEMPLATE = template.Template(u'''
- <h1>hellô {{ user.login }}</h1>
-''')
-
-class MyIndex(StartupView):
- id = 'index'
-
- def call(self):
- ctx = template.Context({'user': self.req.user})
- return INDEX_TEMPLATE.render(ctx)
--- a/goa/test/unittest_db.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-# -*- coding: utf-8 -*-
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-from cubicweb.goa.testlib import *
-
-from cubicweb import Binary
-from cubicweb.goa.goaconfig import GAEConfiguration
-from cubicweb.server.utils import crypt_password
-
-from google.appengine.api.datastore_types import Text, Blob
-
-
-class Blog(db.Model):
- data = db.BlobProperty()
-
-class DBTest(GAEBasedTC):
- config = GAEConfiguration('toto')
- config.global_set_option('use-google-auth', False)
-
- MODEL_CLASSES = (Blog,)
-
- def test_set_none_relation(self):
- eprop = self.add_entity('CWProperty', pkey=u'ui.language', value=u'en')
- self.failUnless('s_for_user' in eprop._dbmodel)
- self.assertEquals(eprop._dbmodel['s_for_user'], None)
-
- def test_euser_key(self):
- euser = self.add_entity('CWUser', login=u'toto', upassword='toto')
- self.assertEquals(euser.key().name(), 'key_toto')
-
- def test_egroup_key(self):
- egroup = self.add_entity('CWGroup', name=u'toto')
- self.assertEquals(egroup.key().name(), 'key_toto')
-
- def test_password_encryption(self):
- euser = self.add_entity('CWUser', login=u'toto', upassword='toto')
- self.failUnless(euser.upassword != 'toto', euser.upassword)
- self.assertEquals(crypt_password('toto', euser.upassword[:2]), euser.upassword)
-
- def test_long_text(self):
- # datastore string type is limited to 500 bytes
- text = u'e'*501
- entity = self.add_entity('State', name=u'test', description=text)
- self.assertIsInstance(entity.description, unicode)
- self.failIf(isinstance(entity.description, Text))
- self.assertEquals(entity.description, text)
-
- def test_long_accentued_text(self):
- # datastore string type is limited to 500 bytes
- text = u'é'*500
- entity = self.add_entity('State', name=u'test', description=text)
- self.assertIsInstance(entity.description, unicode)
- self.failIf(isinstance(entity.description, Text))
- self.assertEquals(entity.description, text)
-
- def test_blob(self):
- data = 'e'*501
- entity = self.add_entity('Blog', data=data)
- self.assertIsInstance(entity.data, Binary)
- value = entity.data.getvalue()
- self.failIf(isinstance(value, Blob))
- self.assertEquals(value, data)
-
-
-if __name__ == '__main__':
- from logilab.common.testlib import unittest_main
- unittest_main()
--- a/goa/test/unittest_editcontroller.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,430 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-from cubicweb.goa.testlib import *
-
-from urllib import unquote
-
-from cubicweb import ValidationError
-from cubicweb.uilib import rql_for_eid
-
-from cubicweb.web import INTERNAL_FIELD_VALUE, Redirect
-
-from cubicweb.goa.goaconfig import GAEConfiguration
-from cubicweb.entities.authobjs import CWUser
-
-
-class EditControllerTC(GAEBasedTC):
-
- config = GAEConfiguration('toto')
- config.global_set_option('use-google-auth', False)
- config.global_set_option('schema-type', 'yams')
- config.global_set_option('included-cubes', ())
- config.global_set_option('included-yams-cubes', ('blog',))
-
- MODEL_CLASSES = ()
- from cubicweb.web.views import editcontroller
- from cubicweb.entities import lib
- LOAD_APP_MODULES = (editcontroller, lib)
-
- def setUp(self):
- GAEBasedTC.setUp(self)
- self.req = self.request()
- self.ctrl = self.get_ctrl(self.req)
-
- def get_ctrl(self, req):
- return self.vreg.select('controllers', 'edit', req=req, appli=self)
-
- def publish(self, req):
- assert req is self.ctrl.req
- try:
- result = self.ctrl.publish()
- req.cnx.commit()
- except Redirect:
- req.cnx.commit()
- raise
- except:
- req.cnx.rollback()
- raise
- return result
-
- def expect_redirect_publish(self, req=None):
- if req is not None:
- self.ctrl = self.get_ctrl(req)
- else:
- req = self.req
- try:
- res = self.publish(req)
- except Redirect, ex:
- try:
- path, params = ex.location.split('?', 1)
- except:
- path, params = ex.location, ""
- req._url = path
- cleanup = lambda p: (p[0], unquote(p[1]))
- params = dict(cleanup(p.split('=', 1)) for p in params.split('&') if p)
- return req.relative_path(False), params # path.rsplit('/', 1)[-1], params
- else:
- self.fail('expected a Redirect exception')
-
- def test_noparam_edit(self):
- """check behaviour of this controller without any form parameter"""
- self.req.form = {}
- self.assertRaises(ValidationError, self.publish, self.req)
-
- def test_validation_unique(self):
- """test creation of two linked entities"""
- user = self.user
- self.req.form = {'eid': 'X', '__type:X': 'CWUser',
- 'login:X': self.user.login, 'edits-login:X': u'',
- 'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
- }
- self.assertRaises(ValidationError, self.publish, self.req)
-
-
- def test_user_editing_itself(self):
- """checking that a manager user can edit itself"""
- self.skip('missing actual gae support, retry latter')
- user = self.user
- basegroups = [str(eid) for eid, in self.req.execute('CWGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
- groupeids = [eid for eid, in self.req.execute('CWGroup G WHERE G name in ("managers", "users")')]
- groups = [str(eid) for eid in groupeids]
- stateeid = [eid for eid, in self.req.execute('State S WHERE S name "activated"')][0]
- self.req.form = {
- 'eid': user.eid,
- '__type:'+user.eid: 'CWUser',
- 'login:'+user.eid: unicode(user.login),
- 'firstname:'+user.eid: u'Th\xe9nault',
- 'surname:'+user.eid: u'Sylvain',
- 'in_group:'+user.eid: groups,
- 'in_state:'+user.eid: stateeid,
- #
- 'edits-login:'+user.eid: unicode(user.login),
- 'edits-firstname:'+user.eid: u'',
- 'edits-surname:'+user.eid: u'',
- 'edits-in_group:'+user.eid: basegroups,
- 'edits-in_state:'+user.eid: stateeid,
- }
- path, params = self.expect_redirect_publish()
- e = self.req.execute('Any X WHERE X eid %(x)s', {'x': user.eid}, 'x').get_entity(0, 0)
- self.assertEquals(e.firstname, u'Th\xe9nault')
- self.assertEquals(e.surname, u'Sylvain')
- self.assertEquals(e.login, user.login)
- self.assertEquals([g.eid for g in e.in_group], groupeids)
- self.assertEquals(e.in_state[0].eid, stateeid)
-
- def test_user_can_change_its_password(self):
- user = self.create_user('user')
- cnx = self.login('user')
- req = self.request()
- #self.assertEquals(self.ctrl.schema['CWUser']._groups['read'],
- # ('managers', 'users'))
- req.form = {
- 'eid': user.eid, '__type:'+user.eid: 'CWUser',
- '__maineid' : str(user.eid),
- 'upassword:'+user.eid: 'tournicoton',
- 'upassword-confirm:'+user.eid: 'tournicoton',
- 'edits-upassword:'+user.eid: '',
- }
- path, params = self.expect_redirect_publish(req)
- cnx.commit() # commit to check we don't get late validation error for instance
- self.assertEquals(path, 'euser/user')
- self.failIf('vid' in params)
-
- def test_user_editing_itself_no_relation(self):
- """checking we can edit an entity without specifying some required
- relations (meaning no changes)
- """
- user = self.user
- groupeids = [eid for eid, in self.req.execute('CWGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
- self.req.form = {
- 'eid': user.eid,
- '__type:'+user.eid: 'CWUser',
- 'login:'+user.eid: unicode(user.login),
- 'firstname:'+user.eid: u'Th\xe9nault',
- 'surname:'+user.eid: u'Sylvain',
- #
- 'edits-login:'+user.eid: unicode(user.login),
- 'edits-firstname:'+user.eid: u'',
- 'edits-surname:'+user.eid: u'',
- }
- path, params = self.expect_redirect_publish()
- self.req.drop_entity_cache(user.eid)
- e = self.req.execute('Any X WHERE X eid %(x)s', {'x': user.eid}, 'x').get_entity(0, 0)
- self.assertEquals(e.login, user.login)
- self.assertEquals(e.firstname, u'Th\xe9nault')
- self.assertEquals(e.surname, u'Sylvain')
- self.assertUnorderedIterableEquals([g.eid for g in e.in_group], groupeids)
- #stateeids = [eid for eid, in self.req.execute('State S WHERE S name "activated"')]
- #self.assertEquals([s.eid for s in e.in_state], stateeids)
-
-
- def test_create_multiple_linked(self):
- gueid = self.req.execute('CWGroup G WHERE G name "users"')[0][0]
- self.req.form = {'eid': ['X', 'Y'],
-
- '__type:X': 'CWUser',
- '__maineid' : 'X',
- 'login:X': u'adim', 'edits-login:X': u'',
- 'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
- 'surname:X': u'Di Mascio', 'edits-surname:X': '',
-
- 'in_group:X': gueid, 'edits-in_group:X': INTERNAL_FIELD_VALUE,
-
- '__type:Y': 'EmailAddress',
- 'address:Y': u'dima@logilab.fr', 'edits-address:Y': '',
- 'use_email:X': 'Y', 'edits-use_email:X': INTERNAL_FIELD_VALUE,
- }
- path, params = self.expect_redirect_publish()
- # should be redirected on the created person
- self.assertEquals(path, 'euser/adim')
- e = self.req.execute('Any P WHERE P surname "Di Mascio"').get_entity(0, 0)
- self.assertEquals(e.surname, 'Di Mascio')
- email = e.use_email[0]
- self.assertEquals(email.address, 'dima@logilab.fr')
-
- def test_edit_multiple_linked(self):
- peid = self.create_user('adim').eid
- self.req.form = {'eid': [peid, 'Y'],
- '__type:%s'%peid: 'CWUser',
- 'surname:%s'%peid: u'Di Masci', 'edits-surname:%s'%peid: '',
-
- '__type:Y': 'EmailAddress',
- 'address:Y': u'dima@logilab.fr', 'edits-address:Y': '',
- 'use_email:%s'%peid: 'Y', 'edits-use_email:%s'%peid: INTERNAL_FIELD_VALUE,
-
- '__redirectrql': 'Any X WHERE X eid %s'%peid,
- }
- path, params = self.expect_redirect_publish()
- # should be redirected on the created person
- eid = params['rql'].split()[-1]
- e = self.req.execute('Any X WHERE X eid %(x)s', {'x': eid}, 'x').get_entity(0, 0)
- self.assertEquals(e.surname, 'Di Masci')
- email = e.use_email[0]
- self.assertEquals(email.address, 'dima@logilab.fr')
-
- emaileid = email.eid
- self.req.form = {'eid': [peid, emaileid],
- '__type:%s'%peid: 'CWUser',
- 'surname:%s'%peid: u'Di Masci', 'edits-surname:%s'%peid: 'Di Masci',
- '__type:%s'%emaileid: 'EmailAddress',
- 'address:%s'%emaileid: u'adim@logilab.fr', 'edits-address:%s'%emaileid: 'dima@logilab.fr',
- 'use_email:%s'%peid: emaileid, 'edits-use_email:%s'%peid: emaileid,
- '__redirectrql': 'Any X WHERE X eid %s'%peid,
- }
- path, params = self.expect_redirect_publish()
- # should be redirected on the created person
- eid = params['rql'].split()[-1]
- # XXX this should not be necessary, it isn't with regular cubicweb
- self.req._eid_cache = {}
- e = self.req.execute('Any X WHERE X eid %(x)s', {'x': eid}, 'x').get_entity(0, 0)
- self.assertEquals(e.surname, 'Di Masci')
- email = e.use_email[0]
- self.assertEquals(email.address, 'adim@logilab.fr')
-
-
- def test_password_confirm(self):
- """test creation of two linked entities
- """
- user = self.user
- self.req.form = {'__cloned_eid:X': user.eid,
- 'eid': 'X', '__type:X': 'CWUser',
- 'login:X': u'toto', 'edits-login:X': u'',
- 'upassword:X': u'toto', 'edits-upassword:X': u'',
- }
- self.assertRaises(ValidationError, self.publish, self.req)
- self.req.form = {'__cloned_eid:X': user.eid,
- 'eid': 'X', '__type:X': 'CWUser',
- 'login:X': u'toto', 'edits-login:X': u'',
- 'upassword:X': u'toto', 'upassword-confirm:X': u'tutu', 'edits-upassword:X': u'',
- }
- self.assertRaises(ValidationError, self.publish, self.req)
-
-
- def test_req_pending_insert(self):
- """make sure req's pending insertions are taken into account"""
- tmpgroup = self.add_entity('CWGroup', name=u"test")
- user = self.user
- self.req.set_session_data('pending_insert', set([(user.eid, 'in_group', tmpgroup.eid)]))
- path, params = self.expect_redirect_publish()
- usergroups = [gname for gname, in
- self.req.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
- self.assertUnorderedIterableEquals(usergroups, ['managers', 'users', 'test'])
- self.assertEquals(self.req.get_pending_inserts(), [])
-
-
- def test_req_pending_delete(self):
- """make sure req's pending deletions are taken into account"""
- user = self.user
- groupeid = self.req.execute('INSERT CWGroup G: G name "test", U in_group G WHERE U eid %(x)s',
- {'x': user.eid})[0][0]
- usergroups = [gname for gname, in
- self.req.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
- # just make sure everything was set correctly
- self.assertUnorderedIterableEquals(usergroups, ['managers', 'users', 'test'])
- # now try to delete the relation
- self.req.set_session_data('pending_delete', set([(user.eid, 'in_group', groupeid)]))
- path, params = self.expect_redirect_publish()
- usergroups = [gname for gname, in
- self.req.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
- self.assertUnorderedIterableEquals(usergroups, ['managers', 'users'])
- #self.assertUnorderedIterableEquals(usergroups, ['managers'])
- self.assertEquals(self.req.get_pending_deletes(), [])
-
- def test_custom_attribute_handler(self):
- def custom_login_edit(self, formparams, value, relations):
- formparams['login'] = value.upper()
- relations.append('X login %(login)s')
- CWUser.custom_login_edit = custom_login_edit
- try:
- user = self.user
- eid = repr(user.eid)
- self.req.form = {
- 'eid': eid,
- '__type:'+eid: 'CWUser',
- 'login:'+eid: u'foo',
- 'edits-login:'+eid: unicode(user.login),
- }
- path, params = self.expect_redirect_publish()
- rset = self.req.execute('Any L WHERE X eid %(x)s, X login L', {'x': user.eid}, 'x')
- self.assertEquals(rset[0][0], 'FOO')
- finally:
- del CWUser.custom_login_edit
-
- def test_redirect_apply_button(self):
- redirectrql = rql_for_eid(4012) # whatever
- self.req.form = {
- 'eid': 'A', '__type:A': 'BlogEntry',
- '__maineid' : 'A',
- 'content:A': u'"13:03:43"', 'edits-content:A': '',
- 'title:A': u'huuu', 'edits-title:A': '',
- '__redirectrql': redirectrql,
- '__redirectvid': 'primary',
- '__redirectparams': 'toto=tutu&tata=titi',
- '__form_id': 'edition',
- '__action_apply': '',
- }
- path, params = self.expect_redirect_publish()
- self.failUnless(path.startswith('blogentry/'))
- eid = path.split('/')[1]
- self.assertEquals(params['vid'], 'edition')
- self.assertNotEquals(eid, '4012')
- self.assertEquals(params['__redirectrql'], redirectrql)
- self.assertEquals(params['__redirectvid'], 'primary')
- self.assertEquals(params['__redirectparams'], 'toto=tutu&tata=titi')
-
- def test_redirect_ok_button(self):
- redirectrql = rql_for_eid(4012) # whatever
- self.req.form = {
- 'eid': 'A', '__type:A': 'BlogEntry',
- '__maineid' : 'A',
- 'content:A': u'"13:03:43"', 'edits-content:A': '',
- 'title:A': u'huuu', 'edits-title:A': '',
- '__redirectrql': redirectrql,
- '__redirectvid': 'primary',
- '__redirectparams': 'toto=tutu&tata=titi',
- '__form_id': 'edition',
- }
- path, params = self.expect_redirect_publish()
- self.assertEquals(path, 'view')
- self.assertEquals(params['rql'], redirectrql)
- self.assertEquals(params['vid'], 'primary')
- self.assertEquals(params['tata'], 'titi')
- self.assertEquals(params['toto'], 'tutu')
-
- def test_redirect_delete_button(self):
- eid = self.add_entity('BlogEntry', title=u'hop', content=u'hop').eid
- self.req.form = {'eid': str(eid), '__type:%s'%eid: 'BlogEntry',
- '__action_delete': ''}
- path, params = self.expect_redirect_publish()
- self.assertEquals(path, 'blogentry')
- self.assertEquals(params, {u'__message': u'entity deleted'})
- eid = self.add_entity('EmailAddress', address=u'hop@logilab.fr').eid
- self.req.execute('SET X use_email E WHERE E eid %(e)s, X eid %(x)s',
- {'x': self.user.eid, 'e': eid}, 'x')
- self.commit()
- self.req.form = {'eid': str(eid), '__type:%s'%eid: 'EmailAddress',
- '__action_delete': ''}
- path, params = self.expect_redirect_publish()
- self.assertEquals(unquote(path), 'euser/'+self.user.login)
- self.assertEquals(params, {u'__message': u'entity deleted'})
- eid1 = self.add_entity('BlogEntry', title=u'hop', content=u'hop').eid
- eid2 = self.add_entity('EmailAddress', address=u'hop@logilab.fr').eid
- self.req.form = {'eid': [str(eid1), str(eid2)],
- '__type:%s'%eid1: 'BlogEntry',
- '__type:%s'%eid2: 'EmailAddress',
- '__action_delete': ''}
- path, params = self.expect_redirect_publish()
- self.assertEquals(path, 'view')
- self.assertEquals(params, {u'__message': u'entities deleted'})
-
-
- def test_nonregr_multiple_empty_email_addr(self):
- gueid = self.req.execute('CWGroup G WHERE G name "users"')[0][0]
- self.req.form = {'eid': ['X', 'Y'],
-
- '__type:X': 'CWUser',
- 'login:X': u'adim', 'edits-login:X': u'',
- 'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
- 'in_group:X': gueid, 'edits-in_group:X': INTERNAL_FIELD_VALUE,
-
- '__type:Y': 'EmailAddress',
- 'address:Y': u'', 'edits-address:Y': '',
- 'alias:Y': u'', 'edits-alias:Y': '',
- 'use_email:X': 'Y', 'edits-use_email:X': INTERNAL_FIELD_VALUE,
- }
- self.assertRaises(ValidationError, self.publish, self.req)
-
-
- def test_nonregr_rollback_on_validation_error(self):
- self.skip('lax fix me')
- p = self.create_user("doe")
- # do not try to skip 'primary_email' for this test
- old_skips = p.__class__.skip_copy_for
- p.__class__.skip_copy_for = ()
- try:
- e = self.add_entity('EmailAddress', address=u'doe@doe.com')
- self.req.execute('SET P use_email E, P primary_email E WHERE P eid %(p)s, E eid %(e)s',
- {'p' : p.eid, 'e' : e.eid})
- self.req.form = {'__cloned_eid:X': p.eid,
- 'eid': 'X', '__type:X': 'CWUser',
- 'login': u'dodo', 'edits-login': u'dodo',
- 'surname:X': u'Boom', 'edits-surname:X': u'',
- '__errorurl' : "whatever but required",
- }
- # try to emulate what really happens in the web application
- # 1/ validate form => EditController.publish raises a ValidationError
- # which fires a Redirect
- # 2/ When re-publishing the copy form, the publisher implicitly commits
- try:
- self.app.publish('edit', self.req)
- except Redirect:
- self.req.form['rql'] = 'Any X WHERE X eid %s' % p.eid
- self.req.form['vid'] = 'copy'
- self.app.publish('view', self.req)
- rset = self.req.execute('CWUser P WHERE P surname "Boom"')
- self.assertEquals(len(rset), 0)
- finally:
- p.__class__.skip_copy_for = old_skips
-
-
-if __name__ == '__main__':
- from logilab.common.testlib import unittest_main
- unittest_main()
--- a/goa/test/unittest_metadata.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-from cubicweb.goa.testlib import *
-
-import time
-from mx.DateTime import DateTimeType
-from datetime import datetime
-from cubicweb.goa import db
-
-from google.appengine.api import datastore
-
-class Article(db.Model):
- content = db.TextProperty()
- synopsis = db.StringProperty(default='hello')
-
-class Blog(db.Model):
- diem = db.DateProperty(required=True, auto_now_add=True)
- title = db.StringProperty(required=True)
- content = db.TextProperty()
- talks_about = db.ReferenceProperty(Article)
- cites = db.SelfReferenceProperty()
-
-
-class MetaDataTC(GAEBasedTC):
- MODEL_CLASSES = (Article, Blog)
-
- def setUp(self):
- GAEBasedTC.setUp(self)
- self.req = self.request()
- self.a = self.add_entity('Article')
- self.p = self.add_entity('CWProperty', pkey=u'ui.language', value=u'en')
- self.session.commit()
-
- def _test_timestamp(self, entity, attr, sleep=0.1):
- timestamp = getattr(entity, attr)
- self.failUnless(timestamp)
- self.assertIsInstance(timestamp, DateTimeType)
- self.assertIsInstance(entity.to_gae_model()['s_'+attr], datetime)
- time.sleep(sleep)
- if entity.id == 'Article':
- entity.set_attributes(content=u'zou')
- else:
- entity.set_attributes(value=u'en')
- self.session.commit()
- return timestamp
-
- def test_creation_date_dbmodel(self):
- cdate = self._test_timestamp(self.a, 'creation_date')
- self.assertEquals(cdate, self.a.creation_date)
-
- def test_creation_date_yams(self):
- cdate = self._test_timestamp(self.p, 'creation_date')
- self.assertEquals(cdate, self.p.creation_date)
-
- def test_modification_date_dbmodel(self):
- mdate = self._test_timestamp(self.a, 'modification_date', sleep=1)
- a = self.execute('Any X WHERE X eid %(x)s', {'x': self.a.eid}, 'x').get_entity(0, 0)
- self.failUnless(mdate < a.modification_date, (mdate, a.modification_date))
-
- def test_modification_date_yams(self):
- mdate = self._test_timestamp(self.p, 'modification_date', sleep=1)
- p = self.execute('Any X WHERE X eid %(x)s', {'x': self.p.eid}, 'x').get_entity(0, 0)
- self.failUnless(mdate < p.modification_date, (mdate, p.modification_date))
-
- def _test_owned_by(self, entity):
- self.assertEquals(len(entity.owned_by), 1)
- owner = entity.owned_by[0]
- self.assertIsInstance(owner, db.Model)
- dbmodel = entity.to_gae_model()
- self.assertEquals(len(dbmodel['s_owned_by']), 1)
- self.assertIsInstance(dbmodel['s_owned_by'][0], datastore.Key)
-
- def test_owned_by_dbmodel(self):
- self._test_owned_by(self.a)
-
- def test_owned_by_yams(self):
- self._test_owned_by(self.p)
-
- def _test_created_by(self, entity):
- self.assertEquals(len(entity.created_by), 1)
- creator = entity.created_by[0]
- self.assertIsInstance(creator, db.Model)
- self.assertIsInstance(entity.to_gae_model()['s_created_by'], datastore.Key)
-
- def test_created_by_dbmodel(self):
- self._test_created_by(self.a)
-
- def test_created_by_dbmodel(self):
- self._test_created_by(self.p)
-
- def test_user_owns_dbmodel(self):
- self.failUnless(self.req.user.owns(self.a.eid))
-
- def test_user_owns_yams(self):
- self.failUnless(self.req.user.owns(self.p.eid))
-
- def test_is_relation(self):
- en = self.execute('Any EN WHERE E name EN, X is E, X eid %(x)s', {'x': self.a.eid}, 'x')[0][0]
- self.assertEquals(en, 'Article')
- en = self.execute('Any EN WHERE E name EN, X is E, X eid %(x)s', {'x': self.p.eid}, 'x')[0][0]
- self.assertEquals(en, 'CWProperty')
- en = self.execute('Any EN WHERE E name EN, X is E, X eid %(x)s', {'x': self.req.user.eid}, 'x')[0][0]
- self.assertEquals(en, 'CWUser')
-
-
-if __name__ == '__main__':
- from logilab.common.testlib import unittest_main
- unittest_main()
--- a/goa/test/unittest_rql.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,625 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-from cubicweb.goa.testlib import *
-
-from cubicweb import Binary
-
-from logilab.common.testlib import unittest_main
-from mx.DateTime import now, today, DateTimeType
-import rql
-
-from google.appengine.api.datastore_types import Blob, Text
-
-# stored procedure definition #################################################
-
-from rql.utils import register_function, FunctionDescr
-
-class itemtype_sort_value(FunctionDescr):
- supported_backends = ('sqlite',)
- rtype = 'Int'
-
-try:
- register_function(itemtype_sort_value)
-except AssertionError:
- pass
-
-def init_sqlite_connexion(cnx):
- def itemtype_sort_value(text):
- return {"personal":2, "business":1}[text]
- cnx.create_function("ITEMTYPE_SORT_VALUE", 1, itemtype_sort_value)
-
-from cubicweb.server import SQL_CONNECT_HOOKS
-sqlite_hooks = SQL_CONNECT_HOOKS.setdefault('sqlite', [])
-sqlite_hooks.append(init_sqlite_connexion)
-
-# end stored procedure definition #############################################
-
-class Article(db.Model):
- content = db.TextProperty()
- synopsis = db.StringProperty(default=u'hello')
-
-class Blog(db.Model):
- diem = db.DateProperty(required=True, auto_now_add=True)
- content = db.TextProperty()
- itemtype = db.StringProperty(required=True, choices=(u'personal', u'business'))
- talks_about = db.ReferenceProperty(Article)
- cites = db.SelfReferenceProperty()
- data = db.BlobProperty()
-
-
-class RQLTest(GAEBasedTC):
- MODEL_CLASSES = (Article, Blog)
-
- def setUp(self):
- GAEBasedTC.setUp(self)
- # hack to make talks_about cardinality to ** instead of ?*
- self.schema.rschema('talks_about').set_rproperty('Blog', 'Article',
- 'cardinality', '**')
- self.req = self.request()
- self.article = self.add_entity('Article', content=u'very interesting')
- self.blog = self.add_entity('Blog', itemtype=u'personal', content=u'hop')
- self.execute('SET X talks_about Y WHERE X eid %(x)s, Y eid %(y)s',
- {'x': self.blog.eid, 'y': self.article.eid})
- self.commit()
-
- def _check_rset_size(self, rset, row, col):
- self.assertEquals(len(rset), row)
- self.assertEquals(len(rset[0]), col)
- self.assertEquals(len(rset.description), row)
- self.assertEquals(len(rset.description[0]), col)
-
- def _check_blog_rset(self, rset):
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset.description[0][0], 'Blog')
- self.assertEquals(rset[0][0], self.blog.eid)
- self.assertEquals(rset.get_entity(0, 0).eid, self.blog.eid)
-
- def test_0_const(self):
- rset = self.req.execute('Any 1')
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset[0][0], 1)
- self.assertEquals(rset.description[0][0], 'Int')
-
- def test_0_now_const(self):
- rset = self.req.execute('Any NOW')
- self._check_rset_size(rset, 1, 1)
- self.assertIsInstance(rset[0][0], DateTimeType)
- self.assertEquals(rset.description[0][0], 'Datetime')
-
- def test_0_today_const(self):
- rset = self.req.execute('Any TODAY')
- self._check_rset_size(rset, 1, 1)
- self.assertIsInstance(rset[0][0], DateTimeType)
- self.assertEquals(rset[0][0], today())
- self.assertEquals(rset.description[0][0], 'Date')
-
-
- def test_1_eid(self):
- rset = self.req.execute('Any X WHERE X eid %(x)s', {'x': self.blog.eid})
- self._check_blog_rset(rset)
- rset = self.req.execute('Any X WHERE X eid "%s"' % self.blog.eid)
- self._check_blog_rset(rset)
-
- def test_1_eid_eid(self):
- rset = self.req.execute('Any X,Y WHERE X eid %(x)s, Y eid %(y)s', {'x': self.blog.eid,
- 'y': self.article.eid})
- self._check_rset_size(rset, 1, 2)
- self.assertEquals(rset.description[0], ('Blog', 'Article'))
- self.assertEquals(rset[0][0], self.blog.eid)
- self.assertEquals(rset[0][1], self.article.eid)
-
- def test_1_eid_with_is(self):
- self.assertRaises(rql.TypeResolverException,
- self.req.execute, 'Any X WHERE X eid %(x)s, X is Article', {'x': self.blog.eid})
- rset = self.req.execute('Any X WHERE X eid %(x)s, X is Blog', {'x': self.blog.eid})
- self._check_blog_rset(rset)
-
- def test_1_is(self):
- rset = self.req.execute('Any X WHERE X is Blog')
- self._check_blog_rset(rset)
- blog2 = Blog(itemtype=u'personal', content=u'hop')
- blog2.put()
- rset = self.req.execute('Any X WHERE X is Blog')
- self.assertEquals(len(rset), 2)
- self.assertEquals(rset.description, [('Blog',), ('Blog',)])
-
-
- def test_2_attribute_selection_1(self):
- rset = self.req.execute('Any X,D,C WHERE X is Blog, X diem D, X content C')
- self._check_rset_size(rset, 1, 3)
- self.assertEquals(rset[0], [self.blog.eid, today(), u'hop'])
- self.assertEquals(rset.description[0], ('Blog', 'Date', 'String'))
- self.assertIsInstance(rset[0][1], DateTimeType)
-
- def test_2_attribute_selection_2(self):
- rset = self.req.execute('Any D,C WHERE X is Blog, X diem D, X content C')
- self._check_rset_size(rset, 1, 2)
- self.assertEquals(rset[0], [today(), u'hop'])
- self.assertEquals(rset.description[0], ('Date', 'String'))
-
- def test_2_attribute_selection_binary(self):
- rset = self.req.execute('Any D WHERE X is Blog, X data D')
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset[0], [None])
- self.assertEquals(rset.description[0], ('Bytes',))
- self.blog['data'] = Binary('raw data')
- self.blog.put()
- rset = self.req.execute('Any D WHERE X is Blog, X data D')
- self._check_rset_size(rset, 1, 1)
- self.assertIsInstance(rset[0][0], Binary)
- value = rset[0][0].getvalue()
- self.assertIsInstance(value, str)
- self.failIf(isinstance(value, Blob))
- self.assertEquals(value, 'raw data')
- self.assertEquals(rset.description[0], ('Bytes',))
-
- def test_2_attribute_selection_long_text(self):
- self.blog['content'] = text = 'a'*501
- self.blog.put()
- rset = self.req.execute('Any C WHERE X is Blog, X content C')
- self._check_rset_size(rset, 1, 1)
- self.assertIsInstance(rset[0][0], unicode)
- self.failIf(isinstance(rset[0][0], Text))
- self.assertEquals(rset[0][0], text)
-
- def test_2_attribute_selection_transformation(self):
- rset = self.req.execute('Any X,UPPER(C) WHERE X is Blog, X content C')
- self._check_rset_size(rset, 1, 2)
- self.assertEquals(rset[0], [self.blog.eid, u'HOP'])
- self.assertEquals(rset.description[0], ('Blog', 'String',))
-
-
- def test_3_attribute_restriction(self):
- rset = self.req.execute('Any X WHERE X itemtype "personal"')
- self._check_blog_rset(rset)
- rset = self.req.execute('Any X WHERE X itemtype "business"')
- self.assertEquals(len(rset), 0)
-
- def test_3_ambigous_attribute_restriction_1(self):
- rset = self.req.execute('Any X WHERE X content "hello"')
- self.assertEquals(len(rset), 0)
-
- def test_3_ambigous_attribute_restriction_2(self):
- rset = self.req.execute('Any X WHERE X content "hop"')
- self._check_blog_rset(rset)
-
- def test_3_ambigous_attribute_restriction_3(self):
- article = Article(content=u'hop')
- article.put()
- rset = self.req.execute('Any X WHERE X content "hop"')
- self._check_rset_size(rset, 2, 1)
- self.assertUnorderedIterableEquals([r[0] for r in rset], [self.blog.eid, article.eid])
- self.assertUnorderedIterableEquals([r[0] for r in rset.description], ['Blog', 'Article'])
-
- def test_3_incoherant_attribute_restriction(self):
- rset = self.req.execute('Any X WHERE X eid %(x)s, X content "hola"',
- {'x': self.blog.eid})
- self.assertEquals(len(rset), 0)
-
- def test_3_multiple_attribute_restriction(self):
- rset = self.req.execute('Any X WHERE X content "hop", X itemtype "personal"')
- self._check_blog_rset(rset)
-
- def test_3_incoherant_multiple_attribute_restriction(self):
- rset = self.req.execute('Any X WHERE X content "hip", X itemtype "personal"')
- self.assertEquals(len(rset), 0)
-
- def test_3_today_attribute_restriction(self):
- rset = self.req.execute('Any X WHERE X diem < TODAY')
- self.assertEquals(len(rset), 0)
- rset = self.req.execute('Any X WHERE X diem <= TODAY')
- self._check_blog_rset(rset)
- rset = self.req.execute('Any X WHERE X diem > TODAY')
- self.assertEquals(len(rset), 0)
- rset = self.req.execute('Any X WHERE X diem >= TODAY')
- self._check_blog_rset(rset)
-
- def test_3_now_attribute_restriction(self):
- rset = self.req.execute('Any X WHERE X diem < NOW')
- self._check_blog_rset(rset)
- rset = self.req.execute('Any X WHERE X diem <= NOW')
- self._check_blog_rset(rset)
- rset = self.req.execute('Any X WHERE X diem > NOW')
- self.assertEquals(len(rset), 0)
- rset = self.req.execute('Any X WHERE X diem >= NOW')
- self.assertEquals(len(rset), 0)
-
- def test_3_in_attribute_restriction(self):
- self.skip('missing actual gae support, retry latter')
- article2 = Article(content=u'hip')
- rset = self.req.execute('Any X WHERE X content IN ("hop", "hip")')
- self._check_rset_size(rset, 2, 1)
- self.assertUnorderedIterableEquals([r[0] for r in rset], [self.blog.eid, article.eid])
- self.assertUnorderedIterableEquals([r[0] for r in rset.description], ['Blog', 'Article'])
-
- def test_3_like(self):
- repo = self.config.repository()
- versions = repo.get_versions()
- self.assertEquals(versions.keys(), ['cubicweb'])
-
- def _setup_relation_description(self):
- self.article2 = self.add_entity('Article', content=u'hop')
- self.blog2 = self.add_entity('Blog', itemtype=u'personal', content=u'hip')
- self.execute('SET X talks_about Y WHERE X eid %(x)s, Y eid %(y)s',
- {'x': self.blog2.eid, 'y': self.article2.eid})
- self.blog3 = self.add_entity('Blog', itemtype=u'business', content=u'hep')
- self.commit()
-
- def test_4_relation_restriction_1(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X WHERE X talks_about Y')
- self._check_rset_size(rset, 2, 1)
- self.assertUnorderedIterableEquals([r[0] for r in rset],
- [self.blog.eid, self.blog2.eid])
- self.assertUnorderedIterableEquals([r[0] for r in rset.description], ['Blog', 'Blog'])
-
- def test_4_relation_restriction_2(self):
- self._setup_relation_description()
- rset = self.req.execute('Any Y WHERE X talks_about Y')
- self._check_rset_size(rset, 2, 1)
- self.assertUnorderedIterableEquals([r[0] for r in rset],
- [self.article.eid, self.article2.eid])
- self.assertUnorderedIterableEquals([r[0] for r in rset.description],
- ['Article', 'Article'])
-
- def test_4_relation_restriction_3(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X,Y WHERE X talks_about Y')
- self._check_rset_size(rset, 2, 2)
- self.assertUnorderedIterableEquals([tuple(r) for r in rset],
- [(self.blog.eid, self.article.eid),
- (self.blog2.eid, self.article2.eid)])
- self.assertUnorderedIterableEquals([tuple(r) for r in rset.description],
- [('Blog', 'Article'),
- ('Blog', 'Article')])
-
- def test_4_relation_restriction_4(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X,Y WHERE X talks_about Y, X eid %(x)s',
- {'x': self.blog.eid})
- self._check_rset_size(rset, 1, 2)
- self.assertEquals(rset[0], [self.blog.eid, self.article.eid])
- self.assertUnorderedIterableEquals(rset.description[0], ['Blog', 'Article'])
-
- def test_4_relation_restriction_5(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X,Y WHERE X talks_about Y, Y eid %(x)s',
- {'x': self.article.eid})
- self._check_rset_size(rset, 1, 2)
- self.assertEquals(rset[0], [self.blog.eid, self.article.eid])
- self.assertUnorderedIterableEquals(rset.description[0], ['Blog', 'Article'])
-
- def test_4_relation_subject_restriction(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X,Y WHERE X talks_about Y, X content %(c)s',
- {'c': 'hop'})
- self._check_rset_size(rset, 1, 2)
- self.assertEquals(rset[0], [self.blog.eid, self.article.eid])
- self.assertUnorderedIterableEquals(rset.description[0], ['Blog', 'Article'])
-
- def test_4_relation_object_restriction(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X WHERE X is Blog, X talks_about Y, Y content %(c)s',
- {'c': 'very interesting'})
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset[0], [self.blog.eid])
- self.assertUnorderedIterableEquals(rset.description[0], ['Blog'])
-
- def test_4_relation_subject_object_restriction(self):
- article2 = self.add_entity('Article', content=u'very interesting')
- rset = self.req.execute('Any X,XC WHERE X is Blog, X content XC, X content %(xc)s, '
- 'X talks_about Y, Y content %(c)s',
- {'xc': 'hop', 'c': 'very interesting'})
- self._check_rset_size(rset, 1, 2)
- self.assertEquals(rset[0], [self.blog.eid, self.blog.content])
- self.assertUnorderedIterableEquals(rset.description[0], ['Blog', 'String'])
-
- def test_4_relation_subject_object_restriction_no_res(self):
- article2 = self.add_entity('Article', content=u'very interesting')
- rset = self.req.execute('Any X,XC WHERE X is Blog, X content XC, X content %(xc)s, '
- 'X talks_about Y, Y content %(c)s',
- {'xc': 'hip', 'c': 'very interesting'})
- self.assertEquals(len(rset), 0)
-
- def test_4_relation_subject_object_restriction_no_res_2(self):
- rset = self.req.execute('Any X,XC WHERE X is Blog, X content XC, X content %(xc)s, '
- 'X talks_about Y, Y content %(c)s',
- {'xc': 'hop', 'c': 'not interesting'})
- self.assertEquals(len(rset), 0)
-
- def test_4_relation_restriction_7(self):
- self._setup_relation_description()
- rset = self.req.execute('Any XC,XD,YC WHERE X talks_about Y, Y eid %(x)s,'
- 'X content XC, X diem XD, Y content YC',
- {'x': self.article.eid})
- self._check_rset_size(rset, 1, 3)
- self.assertEquals(rset[0], [self.blog.content, self.blog.diem, self.article.content])
- self.assertUnorderedIterableEquals(rset.description[0], ['String', 'Date', 'String'])
-
- def test_4_relation_restriction_8(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X,Y WHERE X cites Y, Y eid %(x)s', {'x': self.blog.eid})
- self.assertEquals(len(rset), 0)
-
- def test_4_relation_restriction_9(self):
- article2 = self.add_entity('Article', content=u'hop')
- self.req.execute('SET X talks_about Y WHERE X eid %(x)s, Y eid %(y)s',
- {'x': self.blog.eid, 'y': article2.eid})
- rset = self.req.execute('Any X,Y WHERE X talks_about Y, X eid %(x)s, Y eid %(y)s',
- {'x': self.blog.eid, 'y': article2.eid})
- self._check_rset_size(rset, 1, 2)
-
- def test_4_ambiguous_subject_relation(self):
- ye = self.add_entity('YamsEntity')
- self.req.execute('SET X ambiguous_relation Y WHERE X eid %(x)s, Y eid %(y)s',
- {'x': ye.eid, 'y': self.blog.eid})
- self.req.execute('SET X ambiguous_relation Y WHERE X eid %(x)s, Y eid %(y)s',
- {'x': ye.eid, 'y': self.article.eid})
- self.commit()
- #ye = self.vreg.etype_class('YamsEntity ')(req, None)
- #ye.to_gae_model()['s_ambiguous_relation'] = [self.blog.key(), self.article.key()]
- #ye.put()
- rset = self.req.execute('Any X WHERE Y ambiguous_relation X')
- self._check_rset_size(rset, 2, 1)
- self.assertUnorderedIterableEquals([r[0] for r in rset], [self.blog.eid, self.article.eid])
- self.assertUnorderedIterableEquals([r[0] for r in rset.description], ['Blog', 'Article'])
- rset = self.req.execute('Any X WHERE Y ambiguous_relation X, Y eid %(x)s', {'x': ye.eid})
- self._check_rset_size(rset, 2, 1)
- self.assertUnorderedIterableEquals([r[0] for r in rset], [self.blog.eid, self.article.eid])
- self.assertUnorderedIterableEquals([r[0] for r in rset.description], ['Blog', 'Article'])
-
- def test_4_relation_selection(self):
- req = self.request()
- rset = req.execute('Any N WHERE G content N, U talks_about G, U eid %(u)s', {'u': self.blog.eid})
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset[0][0], 'very interesting')
-
-
- def test_5_orderby(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X,XC ORDERBY XC WHERE X is Blog, X content XC')
- self._check_rset_size(rset, 3, 2)
- self.assertEquals(rset.rows,
- [[self.blog3.eid, 'hep'],
- [self.blog2.eid, 'hip'],
- [self.blog.eid, 'hop']])
-
- def test_5_orderby_desc(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X,XC ORDERBY XC DESC WHERE X is Blog, X content XC')
- self._check_rset_size(rset, 3, 2)
- self.assertEquals(rset.rows,
- [[self.blog.eid, 'hop'],
- [self.blog2.eid, 'hip'],
- [self.blog3.eid, 'hep']])
-
- def test_5_orderby_several_terms(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X,XC,XI ORDERBY XI,XC WHERE X is Blog, X content XC, X itemtype XI')
- self._check_rset_size(rset, 3, 3)
- self.assertEquals(rset.rows,
- [[self.blog3.eid, 'hep', 'business'],
- [self.blog2.eid, 'hip', 'personal'],
- [self.blog.eid, 'hop', 'personal']])
-
- def test_5_orderby_several_terms_mixed_implicit(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X,XC,XI ORDERBY XI,XC DESC WHERE X is Blog, X content XC, X itemtype XI')
- self._check_rset_size(rset, 3, 3)
- self.assertEquals(rset.rows,
- [[self.blog3.eid, 'hep', 'business'],
- [self.blog.eid, 'hop', 'personal'],
- [self.blog2.eid, 'hip', 'personal']])
-
- def test_5_orderby_several_terms_explicit_order(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X,XC,XI ORDERBY XI DESC,XC DESC WHERE X is Blog, X content XC, X itemtype XI')
- self._check_rset_size(rset, 3, 3)
- self.assertEquals(rset.rows,
- [[self.blog.eid, 'hop', 'personal'],
- [self.blog2.eid, 'hip', 'personal'],
- [self.blog3.eid, 'hep', 'business']])
-
- def test_5_orderby_several_terms_mixed_order(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X,XC,XI ORDERBY XI ASC,XC DESC WHERE X is Blog, X content XC, X itemtype XI')
- self._check_rset_size(rset, 3, 3)
- self.assertEquals(rset.rows,
- [[self.blog3.eid, 'hep', 'business'],
- [self.blog.eid, 'hop', 'personal'],
- [self.blog2.eid, 'hip', 'personal']])
-
-
- def test_5_orderby_lower(self):
- blog2 = self.add_entity('Blog', itemtype=u'business', content=u'Hup')
- rset = self.req.execute('Any X ORDERBY LOWER(XC) '
- 'WHERE X is Blog, X content XC')
- self._check_rset_size(rset, 2, 1)
- self.assertEquals(rset.rows, [[self.blog.eid], [blog2.eid]])
- rset = self.req.execute('Any X ORDERBY LOWER(XC) DESC'
- 'WHERE X is Blog, X content XC')
- self._check_rset_size(rset, 2, 1)
- self.assertEquals(rset.rows, [[blog2.eid], [self.blog.eid]])
-
- def test_5_orderby_stored_proc(self):
- blog2 = self.add_entity('Blog', itemtype=u'business', content=u'hop')
- rset = self.req.execute('Any X ORDERBY ITEMTYPE_SORT_VALUE(XIT) '
- 'WHERE X is Blog, X itemtype XIT')
- self._check_rset_size(rset, 2, 1)
- self.assertEquals(rset.rows, [[blog2.eid], [self.blog.eid]])
- rset = self.req.execute('Any X ORDERBY ITEMTYPE_SORT_VALUE(XIT) DESC'
- 'WHERE X is Blog, X itemtype XIT')
- self._check_rset_size(rset, 2, 1)
- self.assertEquals(rset.rows, [[self.blog.eid], [blog2.eid]])
-
-
- def test_6_limit(self):
- self._setup_relation_description()
- rset = self.req.execute('Any X LIMIT 2 WHERE X is Blog')
- self._check_rset_size(rset, 2, 1)
-
- def test_6_offset(self):
- self._setup_relation_description()
- rset = self.req.execute('Any XC ORDERBY XC DESC OFFSET 1 WHERE X is Blog, X content XC')
- self._check_rset_size(rset, 2, 1)
- self.assertEquals(rset.rows, [['hip'], ['hep']])
-
- def test_6_limit_and_orderby(self):
- self._setup_relation_description()
- rset = self.req.execute('Any XC ORDERBY XC LIMIT 2 WHERE X is Blog, X content XC')
- self._check_rset_size(rset, 2, 1)
- self.assertEquals(rset.rows, [['hep'], ['hip']])
-
- def test_6_limit_offset_and_orderby(self):
- self._setup_relation_description()
- rset = self.req.execute('Any XC ORDERBY XC LIMIT 2 OFFSET 0 WHERE X is Blog, X content XC')
- self._check_rset_size(rset, 2, 1)
- self.assertEquals(rset.rows, [['hep'], ['hip']])
- rset = self.req.execute('Any XC ORDERBY XC LIMIT 2 OFFSET 1 WHERE X is Blog, X content XC')
- self._check_rset_size(rset, 2, 1)
- self.assertEquals(rset.rows, [['hip'], ['hop']])
- rset = self.req.execute('Any XC ORDERBY XC LIMIT 2 OFFSET 2 WHERE X is Blog, X content XC')
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset.rows, [['hop']])
- rset = self.req.execute('Any XC ORDERBY XC LIMIT 2 OFFSET 3 WHERE X is Blog, X content XC')
- self.failIf(rset)
-
-
- def test_7_simple_datetimecast(self):
- self._setup_relation_description()
- _today = today()
- _tomorrow = _today + 1
- rset = self.req.execute('Any X WHERE X is Blog, X creation_date >= "%s"'
- % _tomorrow.strftime('%Y-%m-%d'))
- self.failUnless(len(rset) == 0)
- rset = self.req.execute('Any X WHERE X is Blog, X creation_date >= "%s"'
- % _today.strftime('%Y-%m-%d'))
- self._check_rset_size(rset, 3, 1)
- rset = self.req.execute('Any X WHERE X is Blog, X creation_date <= "%s"'
- % _tomorrow.strftime('%Y-%m-%d'))
- self._check_rset_size(rset, 3, 1)
-
- def test_7_identity_relation(self):
- rset = self.req.execute('Any X WHERE X identity Y, X eid %(x)s, Y eid %(y)s',
- {'x': self.user.eid, 'y': self.user.eid})
- self._check_rset_size(rset, 1, 1)
- rset = self.req.execute('Any Y WHERE X identity Y, X eid %(x)s',
- {'x': self.user.eid})
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset.rows, [[self.user.eid]])
- blog2 = self.add_entity('Blog', itemtype=u'personal', content=u'hip')
- rset = self.req.execute('Any X WHERE X identity Y, X eid %(x)s, Y eid %(y)s',
- {'x': self.blog.eid, 'y': blog2.eid})
- self.failIf(rset)
-
- def test_8_not_relation_1(self):
- rset = self.req.execute('Any X WHERE X identity U, NOT U in_group G, '
- 'G name "guests", X eid %(x)s, U eid %(u)s',
- {'x': self.user.eid, 'u': self.user.eid})
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset.rows, [[self.user.eid]])
-
- def test_8_not_relation_linked_subject(self):
- rset = self.req.execute('Any X WHERE NOT X talks_about Y, Y eid %(y)s',
- {'y': self.article.eid})
- self.failIf(rset)
- blog2 = self.add_entity('Blog', content=u'hop', itemtype=u'personal')
- self.commit()
- rset = self.req.execute('Any X WHERE NOT X talks_about Y, Y eid %(y)s',
- {'y': self.article.eid})
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset.rows, [[blog2.eid]])
-
- def test_8_not_relation_linked_object(self):
- rset = self.req.execute('Any Y WHERE NOT X talks_about Y, X eid %(x)s',
- {'x': self.blog.eid})
- self.failIf(rset)
- article2 = self.add_entity('Article', content=u'hop')
- self.commit()
- rset = self.req.execute('Any Y WHERE NOT X talks_about Y, X eid %(x)s',
- {'x': self.blog.eid})
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset.rows, [[article2.eid]])
-
- def test_8_not_relation_linked_attr(self):
- self.skip('not yet implemented')
- # TODO: this should generated
- # Query(X)[s_talks_about] > "hop" || Query(X)[s_talks_about] < "hop"
- article2 = self.add_entity('Article', content=u'hop')
- self.req.execute('SET X talks_about Y WHERE X eid %(x)s, Y eid %(y)s',
- {'x': self.blog.eid, 'y': article2.eid})
- self.commit()
- rset = self.req.execute('Any X WHERE NOT X talks_about Y, Y content "hop"')
- self._check_rset_size(rset, 1, 2)
- self.assertEquals(rset.rows, [[self.blog.eid, self.article.eid]])
-
- def test_8_not_relation_unlinked_subject(self):
- blog2 = self.add_entity('Blog', content=u'hop', itemtype=u'personal')
- self.commit()
- rset = self.req.execute('Any X WHERE NOT X talks_about Y')
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset.rows, [[blog2.eid]])
-
- def test_8_not_relation_unlinked_object(self):
- article2 = self.add_entity('Article', content=u'hop')
- self.commit()
- rset = self.req.execute('Any Y WHERE NOT X talks_about Y')
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset.rows, [[article2.eid]])
-
- def test_8_not_relation_final_1(self):
- rset = self.req.execute('Any G WHERE G is CWGroup, NOT G name "guests"')
- self._check_rset_size(rset, 2, 1)
- self.assertUnorderedIterableEquals([g.name for g in rset.entities()],
- ['users', 'managers'])
-
- def test_8_not_relation_final_2(self):
- rset = self.req.execute('Any GN WHERE G is CWGroup, NOT G name "guests", G name GN')
- self._check_rset_size(rset, 2, 1)
- self.assertUnorderedIterableEquals([gn for gn, in rset.rows],
- ['users', 'managers'])
-
-
- def test_9_exists(self):
- blog2 = self.add_entity('Article', content=u'hop')
- article2 = self.add_entity('Article', content=u'hop')
- self.req.execute('SET X talks_about Y WHERE X eid %(x)s, Y eid %(y)s',
- {'x': self.blog.eid, 'y': article2.eid})
- self.commit()
- rset = self.req.execute('Any X WHERE X is Blog, EXISTS(X talks_about Y)')
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset.rows, [[self.blog.eid]])
-
-
- def test_error_unknown_eid(self):
- rset = self.req.execute('Any X WHERE X eid %(x)s', {'x': '1234'})
- self.assertEquals(len(rset), 0)
- self.blog.cw_delete()
- rset = self.req.execute('Any X WHERE X eid %(x)s', {'x': self.blog.eid})
- self.assertEquals(len(rset), 0)
-
- def test_nonregr_inlined_relation(self):
- eid = self.execute('INSERT YamsEntity X: X inlined_relation Y WHERE Y eid %(y)s',
- {'y': self.blog.eid})[0][0]
- self.commit()
- rset = self.execute('Any X WHERE Y inlined_relation X, Y eid %(y)s', {'y': eid})
- self._check_rset_size(rset, 1, 1)
- self.assertEquals(rset[0][0], self.blog.eid)
-
-if __name__ == '__main__':
- unittest_main()
--- a/goa/test/unittest_schema.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-from cubicweb.goa.testlib import *
-
-class Article(db.Model):
- content = db.TextProperty()
- synopsis = db.StringProperty(default='hello')
-
-class Blog(db.Model):
- diem = db.DateProperty(required=True, auto_now_add=True)
- title = db.StringProperty(required=True)
- content = db.TextProperty()
- talks_about = db.ReferenceProperty(Article)
- cites = db.SelfReferenceProperty()
-
-
-class SomeViewsTC(GAEBasedTC):
- MODEL_CLASSES = (Article, Blog)
-
- def test_entities_and_relation(self):
- schema = self.schema
- self.assertSetEquals(set(str(e) for e in schema.entities()),
- set(('Boolean', 'Bytes', 'Date', 'Datetime', 'Float',
- 'Decimal',
- 'Int', 'Interval', 'Password', 'String', 'Time',
- 'CWEType', 'CWGroup', 'CWPermission', 'CWProperty', 'CWRType',
- 'CWUser', 'EmailAddress',
- 'RQLExpression', 'State', 'Transition', 'TrInfo',
- 'Article', 'Blog', 'YamsEntity')))
- self.assertSetEquals(set(str(e) for e in schema.relations()),
- set(('add_permission', 'address', 'alias', 'allowed_transition',
- 'ambiguous_relation', 'canonical', 'cites',
- 'comment', 'comment_format', 'condition', 'content',
- 'created_by', 'creation_date', 'delete_permission',
- 'description', 'description_format', 'destination_state',
- 'diem', 'eid', 'expression', 'exprtype', 'final', 'firstname',
- 'for_user', 'from_state', 'fulltext_container', 'has_text',
- 'identical_to', 'identity', 'in_group', 'initial_state',
- 'inlined', 'inlined_relation', 'is', 'is_instance_of',
- 'label', 'last_login_time', 'login',
- 'mainvars', 'meta', 'modification_date', 'name', 'owned_by', 'pkey', 'primary_email',
- 'read_permission', 'require_group', 'state_of', 'surname', 'symmetric',
- 'synopsis', 'talks_about', 'title', 'to_state', 'transition_of',
- 'update_permission', 'use_email', 'value')))
-
- def test_dbmodel_imported(self):
- eschema = self.schema['Blog']
- orels = [str(e) for e in eschema.ordered_relations()]
- # only relations defined in the class are actually ordered
- orels, others = orels[:5], orels[5:]
- self.assertEquals(orels,
- ['diem', 'title', 'content', 'talks_about', 'cites'])
- self.assertUnorderedIterableEquals(others,
- ['eid', 'identity', 'owned_by', 'modification_date',
- 'created_by', 'creation_date', 'is', 'is_instance_of'])
- self.assertUnorderedIterableEquals((str(e) for e in eschema.object_relations()),
- ('ambiguous_relation', 'cites', 'identity', 'inlined_relation'))
- eschema = self.schema['Article']
- orels = [str(e) for e in eschema.ordered_relations()]
- # only relations defined in the class are actually ordered
- orels, others = orels[:2], orels[2:]
- self.assertEquals(orels,
- ['content', 'synopsis'])
- self.assertUnorderedIterableEquals(others,
- ['eid', 'identity', 'owned_by', 'modification_date',
- 'created_by', 'creation_date', 'is', 'is_instance_of'])
- self.assertUnorderedIterableEquals((str(e) for e in eschema.object_relations()),
- ('ambiguous_relation', 'talks_about', 'identity'))
-
- def test_yams_imported(self):
- eschema = self.schema['CWProperty']
- # only relations defined in the class are actually ordered
- orels = [str(e) for e in eschema.ordered_relations()]
- orels, others = orels[:3], orels[3:]
- self.assertEquals(orels,
- ['pkey', 'value', 'for_user'])
- self.assertEquals(others,
- ['created_by', 'creation_date', 'eid', 'identity',
- 'is', 'is_instance_of', 'modification_date', 'owned_by'])
- self.assertUnorderedIterableEquals((str(e) for e in eschema.object_relations()),
- ('identity',))
-
- def test_yams_ambiguous_relation(self):
- rschema = self.schema['ambiguous_relation']
- # only relations defined in the class are actually ordered
- self.assertUnorderedIterableEquals((str(e) for e in rschema.subjects()),
- ('YamsEntity',))
- self.assertUnorderedIterableEquals((str(e) for e in rschema.objects()),
- ('Blog', 'Article'))
-
- def test_euser(self):
- eschema = self.schema['CWUser']
- # XXX pretend to have some relations it has not
- self.assertEquals([str(e) for e in eschema.ordered_relations()],
- ['login', 'firstname', 'surname', 'last_login_time',
- 'primary_email', 'use_email', 'in_group', 'created_by',
- 'creation_date', 'eid', 'has_text', 'identity',
- 'is', 'is_instance_of', 'modification_date',
- 'owned_by'])
- self.assertUnorderedIterableEquals((str(e) for e in eschema.object_relations()),
- ('owned_by', 'created_by', 'identity', 'for_user'))
-
- def test_eid(self):
- rschema = self.schema['eid']
- self.assertEquals(rschema.objects(), ('Bytes',))
- self.assertEquals(rschema.rproperty('Blog', 'Bytes', 'cardinality'), '?1')
-
-
-if __name__ == '__main__':
- from logilab.common.testlib import unittest_main
- unittest_main()
--- a/goa/test/unittest_views.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-from cubicweb.goa.testlib import *
-
-from cubicweb.interfaces import ICalendarable
-
-
-class Blog(db.Model):
- diem = db.DateProperty(required=True, auto_now_add=True)
- title = db.StringProperty(required=True)
- content = db.TextProperty()
-
- __implements__ = (ICalendarable,)
-
- @property
- def start(self):
- return self.diem
-
- @property
- def stop(self):
- return self.diem
-
- def matching_dates(self, begin, end):
- """calendar views interface"""
- mydate = self.diem
- if mydate:
- return [mydate]
- return []
-
-
-class SomeViewsTC(GAEBasedTC):
- MODEL_CLASSES = (Blog, )
- from cubicweb.web.views import basecontrollers, baseviews, navigation, boxes, calendar
- from data import views
- LOAD_APP_MODULES = (basecontrollers, baseviews, navigation, boxes, calendar, views)
-
- def setUp(self):
- GAEBasedTC.setUp(self)
- self.req = self.request()
- self.blog = Blog(title=u'a blog', content=u'hop')
- self.blog.put(self.req)
-
- def test_hcal(self):
- self.vreg['views'].render('hcal', self.req, rset=self.blog.rset)
-
- def test_django_index(self):
- self.vreg['views'].render('index', self.req, rset=None)
-
-for vid in ('primary', 'oneline', 'incontext', 'outofcontext', 'text'):
- setattr(SomeViewsTC, 'test_%s'%vid, lambda self, vid=vid: self.blog.view(vid))
-
-if __name__ == '__main__':
- from logilab.common.testlib import unittest_main
- unittest_main()
--- a/goa/testlib.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-"""
-__docformat__ = "restructuredtext en"
-
-from logilab.common.testlib import TestCase, TestSkipped
-try:
- import google.appengine
-except ImportError:
- raise TestSkipped('Can not import google.appengine. Skip this module')
-
-import os, os.path as osp
-import time
-from shutil import copy
-
-# additional monkey patches necessary in regular cubicweb environment
-from cubicweb.server import rqlannotation
-from cubicweb.goa.overrides import rqlannotation as goarqlannotation
-rqlannotation.SQLGenAnnotator = goarqlannotation.SQLGenAnnotator
-rqlannotation.set_qdata = goarqlannotation.set_qdata
-
-from google.appengine.api import apiproxy_stub_map
-from google.appengine.api import datastore_file_stub
-from google.appengine.ext import db as gdb
-
-from cubicweb.devtools.fake import FakeRequest
-
-from cubicweb.goa import db, do_monkey_patch
-from cubicweb.goa.goavreg import GAEVRegistry
-from cubicweb.goa.goaconfig import GAEConfiguration
-from cubicweb.goa.dbinit import (create_user, create_groups, fix_entities,
- init_persistent_schema, insert_versions)
-
-import logging
-logger = logging.getLogger()
-logger.setLevel(logging.CRITICAL)
-
-do_monkey_patch()
-
-class GAEBasedTC(TestCase):
- APP_ID = u'test_app'
- AUTH_DOMAIN = 'gmail.com'
- LOGGED_IN_USER = u't...@example.com' # set to '' for no logged in user
- MODEL_CLASSES = None
- LOAD_APP_MODULES = None
- config = None
- _DS_TEMPL_FILE = 'tmpdb-template'
-
- def load_schema_hook(self, loader):
- loader.import_yams_cube_schema('data')
-
- @property
- def DS_FILE(self):
- return self.DS_TEMPL_FILE.replace('-template', '')
-
- @property
- def DS_TEMPL_FILE(self):
- return self._DS_TEMPL_FILE + '_'.join(sorted(cls.__name__ for cls in self.MODEL_CLASSES))
-
- def _set_ds_file(self, dsfile):
- # Start with a fresh api proxy.
- apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()
- # Use a fresh stub datastore.
- stub = datastore_file_stub.DatastoreFileStub(self.APP_ID, dsfile,
- dsfile+'.history')
- apiproxy_stub_map.apiproxy.RegisterStub('datastore_v3', stub)
-
- def setUp(self):
- # Ensure we're in UTC.
- os.environ['TZ'] = 'UTC'
- time.tzset()
- if osp.exists(self.DS_TEMPL_FILE):
- copy(self.DS_TEMPL_FILE, self.DS_FILE)
- need_ds_init = False
- self._set_ds_file(self.DS_FILE)
- else:
- need_ds_init = True
- self._set_ds_file(self.DS_TEMPL_FILE)
-# from google.appengine.api import mail_stub
-# from google3.apphosting.api import urlfetch_stub
-# from google3.apphosting.api import user_service_stub
-# # Use a fresh stub UserService.
-# apiproxy_stub_map.apiproxy.RegisterStub(
-# 'user', user_service_stub.UserServiceStub())
- os.environ['AUTH_DOMAIN'] = self.AUTH_DOMAIN
- os.environ['USER_EMAIL'] = self.LOGGED_IN_USER
-# # Use a fresh urlfetch stub.
-# apiproxy_stub_map.apiproxy.RegisterStub(
-# 'urlfetch', urlfetch_stub.URLFetchServiceStub())
-# # Use a fresh mail stub.
-# apiproxy_stub_map.apiproxy.RegisterStub(
-# 'mail', mail_stub.MailServiceStub())
- if self.MODEL_CLASSES is None:
- raise Exception('GAEBasedTC should set MODEL_CLASSES class attribute')
- gdb._kind_map = {}
- self.config = self.config or GAEConfiguration('toto')
- self.config.init_log(logging.CRITICAL)
- self.schema = self.config.load_schema(self.MODEL_CLASSES,
- self.load_schema_hook)
- self.vreg = GAEVregistry(self.config)
- self.vreg.schema = self.schema
- self.vreg.load_module(db)
- from cubicweb.goa.appobjects import sessions
- self.vreg.load_module(sessions)
- from cubicweb.entities import authobjs, schemaobjs
- self.vreg.load_module(authobjs)
- self.vreg.load_module(schemaobjs)
- if self.config['use-google-auth']:
- from cubicweb.goa.appobjects import gauthservice
- self.vreg.load_module(gauthservice)
- if self.LOAD_APP_MODULES is not None:
- for module in self.LOAD_APP_MODULES:
- self.vreg.load_module(module)
- for cls in self.MODEL_CLASSES:
- self.vreg.register(cls)
- self.session_manager = self.vreg.select('components', 'sessionmanager')
- if need_ds_init:
- # create default groups and create entities according to the schema
- create_groups()
- if not self.config['use-google-auth']:
- create_user(self.LOGGED_IN_USER, 'toto', ('users', 'managers'))
- self.session = self.login(self.LOGGED_IN_USER, 'toto')
- else:
- req = FakeRequest(vreg=self.vreg)
- self.session = self.session_manager.open_session(req)
- self.user = self.session.user()
- ssession = self.config.repo_session(self.session.sessionid)
- ssession.set_pool()
- init_persistent_schema(ssession, self.schema)
- insert_versions(ssession, self.config)
- ssession.commit()
- fix_entities(self.schema)
- copy(self.DS_TEMPL_FILE, self.DS_FILE)
- self._set_ds_file(self.DS_FILE)
- else:
- if not self.config['use-google-auth']:
- self.session = self.login(self.LOGGED_IN_USER, 'toto')
- else:
- req = FakeRequest(vreg=self.vreg)
- self.session = self.session_manager.open_session(req)
- self.user = self.session.user()
-
- def tearDown(self):
- self.session.close()
-
- def request(self):
- req = FakeRequest(vreg=self.vreg)
- req.set_connection(self.session, self.user)
- return req
-
- def add_entity(self, etype, **kwargs):
- cu = self.session.cursor()
- rql = 'INSERT %s X' % etype
- if kwargs:
- rql += ': %s' % ', '.join('X %s %%(%s)s' % (key, key) for key in kwargs)
- rset = cu.execute(rql, kwargs)
- return rset.get_entity(0, 0)
-
- def execute(self, *args):
- return self.session.cursor().execute(*args)
-
- def commit(self):
- self.session.commit()
-
- def rollback(self):
- self.session.rollback()
-
- def create_user(self, login, groups=('users',), req=None):
- assert not self.config['use-google-auth']
- user = self.add_entity('CWUser', upassword=str(login), login=unicode(login))
- cu = self.session.cursor()
- cu.execute('SET X in_group G WHERE X eid %%(x)s, G name IN(%s)'
- % ','.join(repr(g) for g in groups),
- {'x': user.eid}, 'x')
- return user
-
- def login(self, login, password=None):
- assert not self.config['use-google-auth']
- req = FakeRequest(vreg=self.vreg)
- req.form['__login'] = login
- req.form['__password'] = password or login
- return self.session_manager.open_session(req)
--- a/goa/tools/__init__.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""lax tools cube
-
-"""
--- a/goa/tools/generate_schema_img.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
-import sys
-from os.path import dirname, abspath, join
-from yams import schema2dot
-from cubicweb.web.views.schema import SKIP_TYPES
-
-APPLROOT = abspath(join(dirname(abspath(__file__)), '..'))
-
-try:
- import custom
-except ImportError:
- sys.path.insert(0, APPLROOT)
- import custom
-
-
-schema = custom.SCHEMA
-skip_rels = ('owned_by', 'created_by', 'identity', 'is', 'is_instance_of')
-path = join(APPLROOT, 'data', 'schema.png')
-schema2dot.schema2dot(schema, path, #size=size,
- skiptypes=SKIP_TYPES)
-print 'generated', path
-path = join(APPLROOT, 'data', 'metaschema.png')
-schema2dot.schema2dot(schema, path)
-print 'generated', path
--- a/goa/tools/laxctl.py Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,269 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""provides all lax instances management commands into a single utility script
-
-"""
-__docformat__ = "restructuredtext en"
-
-import sys
-import os
-import os.path as osp
-import time
-import re
-import urllib2
-from urllib import urlencode
-from Cookie import SimpleCookie
-
-from logilab.common.clcommands import Command, register_commands, main_run
-
-from cubicweb.uilib import remove_html_tags
-from cubicweb.web.views.schema import SKIP_TYPES
-
-APPLROOT = osp.abspath(osp.join(osp.dirname(osp.abspath(__file__)), '..'))
-
-
-def initialize_vregistry(applroot):
- # apply monkey patches first
- from cubicweb.goa import do_monkey_patch
- do_monkey_patch()
- from cubicweb.goa.goavreg import GAEVregistry
- from cubicweb.goa.goaconfig import GAEConfiguration
- #WebConfiguration.uiprops['JAVASCRIPTS'].append('DATADIR/goa.js')
- config = GAEConfiguration('toto', applroot)
- vreg = GAEVregistry(config)
- vreg.set_schema(config.load_schema())
- return vreg
-
-def alistdir(directory):
- return [osp.join(directory, f) for f in os.listdir(directory)]
-
-
-class LaxCommand(Command):
- """base command class for all lax commands
- creates vreg, schema and calls
- """
- min_args = max_args = 0
-
- def run(self, args):
- self.vreg = initialize_vregistry(APPLROOT)
- self._run(args)
-
-
-class GenerateSchemaCommand(LaxCommand):
- """generates the schema's png file"""
- name = 'genschema'
-
- def _run(self, args):
- assert not args, 'no argument expected'
- from yams import schema2dot
- schema = self.vreg.schema
- path = osp.join(APPLROOT, 'data', 'schema.png')
- schema2dot.schema2dot(schema, path, #size=size,
- skiptypes=SKIP_TYPES)
- print 'generated', path
- path = osp.join(APPLROOT, 'data', 'metaschema.png')
- schema2dot.schema2dot(schema, path)
- print 'generated', path
-
-
-class PopulateDataDirCommand(LaxCommand):
- """populate instance's data directory according to used cubes"""
- name = 'populatedata'
-
- def _run(self, args):
- assert not args, 'no argument expected'
- # first clean everything which is a symlink from the data directory
- datadir = osp.join(APPLROOT, 'data')
- if not osp.exists(datadir):
- print 'created data directory'
- os.mkdir(datadir)
- for filepath in alistdir(datadir):
- if osp.islink(filepath):
- print 'removing', filepath
- os.remove(filepath)
- cubes = list(self.vreg.config.cubes()) + ['shared']
- for templ in cubes:
- templpath = self.vreg.config.cube_dir(templ)
- templdatadir = osp.join(templpath, 'data')
- if not osp.exists(templdatadir):
- print 'no data provided by', templ
- continue
- for resource in os.listdir(templdatadir):
- if resource == 'external_resources':
- continue
- if not osp.exists(osp.join(datadir, resource)):
- print 'symlinked %s from %s' % (resource, templ)
- os.symlink(osp.join(templdatadir, resource),
- osp.join(datadir, resource))
-
-
-class NoRedirectHandler(urllib2.HTTPRedirectHandler):
- def http_error_302(self, req, fp, code, msg, headers):
- raise urllib2.HTTPError(req.get_full_url(), code, msg, headers, fp)
- http_error_301 = http_error_303 = http_error_307 = http_error_302
-
-
-class GetSessionIdHandler(urllib2.HTTPRedirectHandler):
- def __init__(self, config):
- self.config = config
-
- def http_error_303(self, req, fp, code, msg, headers):
- cookie = SimpleCookie(headers['Set-Cookie'])
- sessionid = cookie['__session'].value
- print 'session id', sessionid
- setattr(self.config, 'cookie', '__session=' + sessionid)
- return 1 # on exception should be raised
-
-
-class URLCommand(LaxCommand):
- """abstract class for commands doing stuff by accessing the web instance
- """
- min_args = max_args = 1
- arguments = '<site url>'
-
- options = (
- ('cookie',
- {'short': 'C', 'type' : 'string', 'metavar': 'key=value',
- 'default': None,
- 'help': 'session/authentication cookie.'}),
- ('user',
- {'short': 'u', 'type' : 'string', 'metavar': 'login',
- 'default': None,
- 'help': 'user login instead of giving raw cookie string (require lax '
- 'based authentication).'}),
- ('password',
- {'short': 'p', 'type' : 'string', 'metavar': 'password',
- 'default': None,
- 'help': 'user password instead of giving raw cookie string (require '
- 'lax based authentication).'}),
- )
-
- def _run(self, args):
- baseurl = args[0]
- if not baseurl.startswith('http'):
- baseurl = 'http://' + baseurl
- if not baseurl.endswith('/'):
- baseurl += '/'
- self.base_url = baseurl
- if not self.config.cookie and self.config.user:
- # no cookie specified but a user is. Try to open a session using
- # given authentication info
- print 'opening session for', self.config.user
- opener = urllib2.build_opener(GetSessionIdHandler(self.config))
- urllib2.install_opener(opener)
- data = urlencode(dict(__login=self.config.user,
- __password=self.config.password))
- self.open_url(urllib2.Request(baseurl, data))
- opener = urllib2.build_opener(NoRedirectHandler())
- urllib2.install_opener(opener)
- self.do_base_url(baseurl)
-
- def build_req(self, url):
- req = urllib2.Request(url)
- if self.config.cookie:
- req.headers['Cookie'] = self.config.cookie
- return req
-
- def open_url(self, req):
- try:
- return urllib2.urlopen(req)
- except urllib2.HTTPError, ex:
- if ex.code == 302:
- self.error_302(req, ex)
- elif ex.code == 500:
- self.error_500(req, ex)
- else:
- raise
-
- def error_302(self, req, ex):
- print 'authentication required'
- print ('visit %s?vid=authinfo with your browser to get '
- 'authentication info' % self.base_url)
- sys.exit(1)
-
- def error_500(self, req, ex):
- print 'an unexpected error occured on the server'
- print ('you may get more information by visiting '
- '%s' % req.get_full_url())
- sys.exit(1)
-
- def extract_message(self, data):
- match = re.search(r'<div class="message">(.*?)</div>', data.read(), re.M|re.S)
- if match:
- msg = remove_html_tags(match.group(1))
- print msg
- return msg
-
- def do_base_url(self, baseurl):
- raise NotImplementedError()
-
-
-class DSInitCommand(URLCommand):
- """initialize the datastore"""
- name = 'db-init'
-
- options = URLCommand.options + (
- ('sleep',
- {'short': 's', 'type' : 'int', 'metavar': 'nb seconds',
- 'default': None,
- 'help': 'number of seconds to wait between each request to avoid '
- 'going out of quota.'}),
- )
-
- def do_base_url(self, baseurl):
- req = self.build_req(baseurl + '?vid=contentinit')
- while True:
- try:
- data = self.open_url(req)
- except urllib2.HTTPError, ex:
- if ex.code == 303: # redirect
- print 'process completed'
- break
- raise
- msg = self.extract_message(data)
- if msg and msg.startswith('error: '):
- print ('you may to cleanup datastore by visiting '
- '%s?vid=contentclear (ALL ENTITIES WILL BE DELETED)'
- % baseurl)
- break
- if self.config.sleep:
- time.sleep(self.config.sleep)
-
-
-class CleanSessionsCommand(URLCommand):
- """cleanup sessions on the server. This command should usually be called
- regularly by a cron job or equivalent.
- """
- name = "cleansessions"
- def do_base_url(self, baseurl):
- req = self.build_req(baseurl + '?vid=cleansessions')
- data = self.open_url(req)
- self.extract_message(data)
-
-
-register_commands([GenerateSchemaCommand,
- PopulateDataDirCommand,
- DSInitCommand,
- CleanSessionsCommand,
- ])
-
-def run():
- main_run(sys.argv[1:])
-
-if __name__ == '__main__':
- run()
--- a/hooks/test/unittest_hooks.py Thu Sep 23 23:28:58 2010 +0200
+++ b/hooks/test/unittest_hooks.py Wed Sep 29 16:16:32 2010 +0200
@@ -49,7 +49,7 @@
self.commit()
def test_delete_required_relations_object(self):
- self.skip('no sample in the schema ! YAGNI ? Kermaat ?')
+ self.skipTest('no sample in the schema ! YAGNI ? Kermaat ?')
def test_static_vocabulary_check(self):
self.assertRaises(ValidationError,
@@ -63,14 +63,14 @@
self.commit)
def test_inlined(self):
- self.assertEquals(self.repo.schema['sender'].inlined, True)
+ self.assertEqual(self.repo.schema['sender'].inlined, True)
self.execute('INSERT EmailAddress X: X address "toto@logilab.fr", X alias "hop"')
self.execute('INSERT EmailPart X: X content_format "text/plain", X ordernum 1, X content "this is a test"')
eeid = self.execute('INSERT Email X: X messageid "<1234>", X subject "test", X sender Y, X recipients Y, X parts P '
'WHERE Y is EmailAddress, P is EmailPart')[0][0]
self.execute('SET X sender Y WHERE X is Email, Y is EmailAddress')
rset = self.execute('Any S WHERE X sender S, X eid %s' % eeid)
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
def test_composite_1(self):
self.execute('INSERT EmailAddress X: X address "toto@logilab.fr", X alias "hop"')
@@ -81,10 +81,10 @@
self.commit()
self.execute('DELETE Email X')
rset = self.execute('Any X WHERE X is EmailPart')
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
self.commit()
rset = self.execute('Any X WHERE X is EmailPart')
- self.assertEquals(len(rset), 0)
+ self.assertEqual(len(rset), 0)
def test_composite_2(self):
self.execute('INSERT EmailAddress X: X address "toto@logilab.fr", X alias "hop"')
@@ -96,7 +96,7 @@
self.execute('DELETE EmailPart X')
self.commit()
rset = self.execute('Any X WHERE X is EmailPart')
- self.assertEquals(len(rset), 0)
+ self.assertEqual(len(rset), 0)
def test_composite_redirection(self):
self.execute('INSERT EmailAddress X: X address "toto@logilab.fr", X alias "hop"')
@@ -110,74 +110,73 @@
self.execute('SET X parts Y WHERE X messageid "<2345>"')
self.commit()
rset = self.execute('Any X WHERE X is EmailPart')
- self.assertEquals(len(rset), 1)
- self.assertEquals(rset.get_entity(0, 0).reverse_parts[0].messageid, '<2345>')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.get_entity(0, 0).reverse_parts[0].messageid, '<2345>')
def test_unsatisfied_constraints(self):
releid = self.execute('SET U in_group G WHERE G name "owners", U login "admin"')[0][0]
ex = self.assertRaises(ValidationError, self.commit)
- self.assertEquals(ex.errors,
+ self.assertEqual(ex.errors,
{'in_group-object': u'RQLConstraint NOT O name "owners" failed'})
def test_html_tidy_hook(self):
req = self.request()
entity = req.create_entity('Workflow', name=u'wf1', description_format=u'text/html',
description=u'yo')
- self.assertEquals(entity.description, u'yo')
+ self.assertEqual(entity.description, u'yo')
entity = req.create_entity('Workflow', name=u'wf2', description_format=u'text/html',
description=u'<b>yo')
- self.assertEquals(entity.description, u'<b>yo</b>')
+ self.assertEqual(entity.description, u'<b>yo</b>')
entity = req.create_entity('Workflow', name=u'wf3', description_format=u'text/html',
description=u'<b>yo</b>')
- self.assertEquals(entity.description, u'<b>yo</b>')
+ self.assertEqual(entity.description, u'<b>yo</b>')
entity = req.create_entity('Workflow', name=u'wf4', description_format=u'text/html',
description=u'<b>R&D</b>')
- self.assertEquals(entity.description, u'<b>R&D</b>')
+ self.assertEqual(entity.description, u'<b>R&D</b>')
entity = req.create_entity('Workflow', name=u'wf5', description_format=u'text/html',
description=u"<div>c'est <b>l'été")
- self.assertEquals(entity.description, u"<div>c'est <b>l'été</b></div>")
+ self.assertEqual(entity.description, u"<div>c'est <b>l'été</b></div>")
def test_nonregr_html_tidy_hook_no_update(self):
entity = self.request().create_entity('Workflow', name=u'wf1', description_format=u'text/html',
description=u'yo')
entity.set_attributes(name=u'wf2')
- self.assertEquals(entity.description, u'yo')
+ self.assertEqual(entity.description, u'yo')
entity.set_attributes(description=u'R&D<p>yo')
entity.cw_attr_cache.pop('description')
- self.assertEquals(entity.description, u'R&D<p>yo</p>')
-
+ self.assertEqual(entity.description, u'R&D<p>yo</p>')
def test_metadata_cwuri(self):
entity = self.request().create_entity('Workflow', name=u'wf1')
- self.assertEquals(entity.cwuri, self.repo.config['base-url'] + 'eid/%s' % entity.eid)
+ self.assertEqual(entity.cwuri, self.repo.config['base-url'] + 'eid/%s' % entity.eid)
def test_metadata_creation_modification_date(self):
_now = datetime.now()
entity = self.request().create_entity('Workflow', name=u'wf1')
- self.assertEquals((entity.creation_date - _now).seconds, 0)
- self.assertEquals((entity.modification_date - _now).seconds, 0)
+ self.assertEqual((entity.creation_date - _now).seconds, 0)
+ self.assertEqual((entity.modification_date - _now).seconds, 0)
def test_metadata_created_by(self):
entity = self.request().create_entity('Bookmark', title=u'wf1', path=u'/view')
self.commit() # fire operations
- self.assertEquals(len(entity.created_by), 1) # make sure we have only one creator
- self.assertEquals(entity.created_by[0].eid, self.session.user.eid)
+ self.assertEqual(len(entity.created_by), 1) # make sure we have only one creator
+ self.assertEqual(entity.created_by[0].eid, self.session.user.eid)
def test_metadata_owned_by(self):
entity = self.request().create_entity('Bookmark', title=u'wf1', path=u'/view')
self.commit() # fire operations
- self.assertEquals(len(entity.owned_by), 1) # make sure we have only one owner
- self.assertEquals(entity.owned_by[0].eid, self.session.user.eid)
+ self.assertEqual(len(entity.owned_by), 1) # make sure we have only one owner
+ self.assertEqual(entity.owned_by[0].eid, self.session.user.eid)
def test_user_login_stripped(self):
u = self.create_user(' joe ')
tname = self.execute('Any L WHERE E login L, E eid %(e)s',
{'e': u.eid})[0][0]
- self.assertEquals(tname, 'joe')
+ self.assertEqual(tname, 'joe')
self.execute('SET X login " jijoe " WHERE X eid %(x)s', {'x': u.eid})
tname = self.execute('Any L WHERE E login L, E eid %(e)s',
{'e': u.eid})[0][0]
- self.assertEquals(tname, 'jijoe')
+ self.assertEqual(tname, 'jijoe')
@@ -198,15 +197,15 @@
def test_user_group_synchronization(self):
user = self.session.user
- self.assertEquals(user.groups, set(('managers',)))
+ self.assertEqual(user.groups, set(('managers',)))
self.execute('SET X in_group G WHERE X eid %s, G name "guests"' % user.eid)
- self.assertEquals(user.groups, set(('managers',)))
+ self.assertEqual(user.groups, set(('managers',)))
self.commit()
- self.assertEquals(user.groups, set(('managers', 'guests')))
+ self.assertEqual(user.groups, set(('managers', 'guests')))
self.execute('DELETE X in_group G WHERE X eid %s, G name "guests"' % user.eid)
- self.assertEquals(user.groups, set(('managers', 'guests')))
+ self.assertEqual(user.groups, set(('managers', 'guests')))
self.commit()
- self.assertEquals(user.groups, set(('managers',)))
+ self.assertEqual(user.groups, set(('managers',)))
def test_user_composite_owner(self):
ueid = self.create_user('toto').eid
@@ -214,7 +213,7 @@
self.execute('INSERT EmailAddress X: X address "toto@logilab.fr", U use_email X '
'WHERE U login "toto"')
self.commit()
- self.assertEquals(self.execute('Any A WHERE X owned_by U, U use_email X,'
+ self.assertEqual(self.execute('Any A WHERE X owned_by U, U use_email X,'
'U login "toto", X address A')[0][0],
'toto@logilab.fr')
@@ -230,23 +229,23 @@
def test_unexistant_eproperty(self):
ex = self.assertRaises(ValidationError,
self.execute, 'INSERT CWProperty X: X pkey "bla.bla", X value "hop", X for_user U')
- self.assertEquals(ex.errors, {'pkey-subject': 'unknown property key'})
+ self.assertEqual(ex.errors, {'pkey-subject': 'unknown property key'})
ex = self.assertRaises(ValidationError,
self.execute, 'INSERT CWProperty X: X pkey "bla.bla", X value "hop"')
- self.assertEquals(ex.errors, {'pkey-subject': 'unknown property key'})
+ self.assertEqual(ex.errors, {'pkey-subject': 'unknown property key'})
def test_site_wide_eproperty(self):
ex = self.assertRaises(ValidationError,
self.execute, 'INSERT CWProperty X: X pkey "ui.site-title", X value "hop", X for_user U')
- self.assertEquals(ex.errors, {'for_user-subject': "site-wide property can't be set for user"})
+ self.assertEqual(ex.errors, {'for_user-subject': "site-wide property can't be set for user"})
def test_bad_type_eproperty(self):
ex = self.assertRaises(ValidationError,
self.execute, 'INSERT CWProperty X: X pkey "ui.language", X value "hop", X for_user U')
- self.assertEquals(ex.errors, {'value-subject': u'unauthorized value'})
+ self.assertEqual(ex.errors, {'value-subject': u'unauthorized value'})
ex = self.assertRaises(ValidationError,
self.execute, 'INSERT CWProperty X: X pkey "ui.language", X value "hop"')
- self.assertEquals(ex.errors, {'value-subject': u'unauthorized value'})
+ self.assertEqual(ex.errors, {'value-subject': u'unauthorized value'})
class SchemaHooksTC(CubicWebTC):
@@ -266,7 +265,7 @@
self.execute('INSERT CWUser X: X login "admin"')
except ValidationError, ex:
self.assertIsInstance(ex.entity, int)
- self.assertEquals(ex.errors, {'login-subject': 'the value "admin" is already used, use another one'})
+ self.assertEqual(ex.errors, {'login-subject': 'the value "admin" is already used, use another one'})
if __name__ == '__main__':
--- a/hooks/test/unittest_syncschema.py Thu Sep 23 23:28:58 2010 +0200
+++ b/hooks/test/unittest_syncschema.py Wed Sep 29 16:16:32 2010 +0200
@@ -98,7 +98,7 @@
self.execute('Societe2 X WHERE X name "logilab"')
self.execute('SET X concerne2 X WHERE X name "logilab"')
rset = self.execute('Any X WHERE X concerne2 Y')
- self.assertEquals(rset.rows, [[s2eid]])
+ self.assertEqual(rset.rows, [[s2eid]])
# check that when a relation definition is deleted, existing relations are deleted
rdefeid = self.execute('INSERT CWRelation X: X cardinality "**", X relation_type RT, '
' X from_entity E, X to_entity E '
@@ -125,9 +125,9 @@
def test_is_instance_of_insertions(self):
seid = self.execute('INSERT Transition T: T name "subdiv"')[0][0]
is_etypes = [etype for etype, in self.execute('Any ETN WHERE X eid %s, X is ET, ET name ETN' % seid)]
- self.assertEquals(is_etypes, ['Transition'])
+ self.assertEqual(is_etypes, ['Transition'])
instanceof_etypes = [etype for etype, in self.execute('Any ETN WHERE X eid %s, X is_instance_of ET, ET name ETN' % seid)]
- self.assertEquals(sorted(instanceof_etypes), ['BaseTransition', 'Transition'])
+ self.assertEqual(sorted(instanceof_etypes), ['BaseTransition', 'Transition'])
snames = [name for name, in self.execute('Any N WHERE S is BaseTransition, S name N')]
self.failIf('subdiv' in snames)
snames = [name for name, in self.execute('Any N WHERE S is_instance_of BaseTransition, S name N')]
@@ -136,27 +136,27 @@
def test_perms_synchronization_1(self):
schema = self.repo.schema
- self.assertEquals(schema['CWUser'].get_groups('read'), set(('managers', 'users')))
+ self.assertEqual(schema['CWUser'].get_groups('read'), set(('managers', 'users')))
self.failUnless(self.execute('Any X, Y WHERE X is CWEType, X name "CWUser", Y is CWGroup, Y name "users"')[0])
self.execute('DELETE X read_permission Y WHERE X is CWEType, X name "CWUser", Y name "users"')
- self.assertEquals(schema['CWUser'].get_groups('read'), set(('managers', 'users', )))
+ self.assertEqual(schema['CWUser'].get_groups('read'), set(('managers', 'users', )))
self.commit()
- self.assertEquals(schema['CWUser'].get_groups('read'), set(('managers',)))
+ self.assertEqual(schema['CWUser'].get_groups('read'), set(('managers',)))
self.execute('SET X read_permission Y WHERE X is CWEType, X name "CWUser", Y name "users"')
self.commit()
- self.assertEquals(schema['CWUser'].get_groups('read'), set(('managers', 'users',)))
+ self.assertEqual(schema['CWUser'].get_groups('read'), set(('managers', 'users',)))
def test_perms_synchronization_2(self):
schema = self.repo.schema['in_group'].rdefs[('CWUser', 'CWGroup')]
- self.assertEquals(schema.get_groups('read'), set(('managers', 'users', 'guests')))
+ self.assertEqual(schema.get_groups('read'), set(('managers', 'users', 'guests')))
self.execute('DELETE X read_permission Y WHERE X relation_type RT, RT name "in_group", Y name "guests"')
- self.assertEquals(schema.get_groups('read'), set(('managers', 'users', 'guests')))
+ self.assertEqual(schema.get_groups('read'), set(('managers', 'users', 'guests')))
self.commit()
- self.assertEquals(schema.get_groups('read'), set(('managers', 'users')))
+ self.assertEqual(schema.get_groups('read'), set(('managers', 'users')))
self.execute('SET X read_permission Y WHERE X relation_type RT, RT name "in_group", Y name "guests"')
- self.assertEquals(schema.get_groups('read'), set(('managers', 'users')))
+ self.assertEqual(schema.get_groups('read'), set(('managers', 'users')))
self.commit()
- self.assertEquals(schema.get_groups('read'), set(('managers', 'users', 'guests')))
+ self.assertEqual(schema.get_groups('read'), set(('managers', 'users', 'guests')))
def test_nonregr_user_edit_itself(self):
ueid = self.session.user.eid
@@ -187,7 +187,7 @@
self.failIf(self.schema['state_of'].inlined)
self.failIf(self.index_exists('State', 'state_of'))
rset = self.execute('Any X, Y WHERE X state_of Y')
- self.assertEquals(len(rset), 2) # user states
+ self.assertEqual(len(rset), 2) # user states
except:
import traceback
traceback.print_exc()
@@ -198,7 +198,7 @@
self.failUnless(self.schema['state_of'].inlined)
self.failUnless(self.index_exists('State', 'state_of'))
rset = self.execute('Any X, Y WHERE X state_of Y')
- self.assertEquals(len(rset), 2)
+ self.assertEqual(len(rset), 2)
def test_indexed_change(self):
self.session.set_pool()
@@ -317,7 +317,7 @@
rdef = self.schema['Transition'].rdef('type')
cstr = rdef.constraint_by_type('StaticVocabularyConstraint')
if not getattr(cstr, 'eid', None):
- self.skip('start me alone') # bug in schema reloading, constraint's eid not restored
+ self.skipTest('start me alone') # bug in schema reloading, constraint's eid not restored
self.execute('SET X value %(v)s WHERE X eid %(x)s',
{'x': cstr.eid, 'v': u"u'normal', u'auto', u'new'"})
self.execute('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X '
@@ -325,7 +325,7 @@
{'ct': 'SizeConstraint', 'value': u'max=10', 'x': rdef.eid})
self.commit()
cstr = rdef.constraint_by_type('StaticVocabularyConstraint')
- self.assertEquals(cstr.values, (u'normal', u'auto', u'new'))
+ self.assertEqual(cstr.values, (u'normal', u'auto', u'new'))
self.execute('INSERT Transition T: T name "hop", T type "new"')
if __name__ == '__main__':
--- a/i18n.py Thu Sep 23 23:28:58 2010 +0200
+++ b/i18n.py Wed Sep 29 16:16:32 2010 +0200
@@ -15,9 +15,8 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""Some i18n/gettext utilities.
+"""Some i18n/gettext utilities."""
-"""
__docformat__ = "restructuredtext en"
import re
--- a/i18n/en.po Thu Sep 23 23:28:58 2010 +0200
+++ b/i18n/en.po Wed Sep 29 16:16:32 2010 +0200
@@ -956,9 +956,6 @@
msgid "add a new permission"
msgstr ""
-msgid "add_perm"
-msgstr "add permission"
-
# subject and object forms for each relation type
# (no object form for final relation types)
msgid "add_permission"
@@ -1857,9 +1854,6 @@
msgid "delete this relation"
msgstr ""
-msgid "delete_perm"
-msgstr "delete permission"
-
msgid "delete_permission"
msgstr "can be deleted by"
@@ -3087,9 +3081,6 @@
msgid "read"
msgstr ""
-msgid "read_perm"
-msgstr "read permission"
-
msgid "read_permission"
msgstr "can be read by"
@@ -3785,9 +3776,6 @@
msgid "update"
msgstr ""
-msgid "update_perm"
-msgstr "update permission"
-
msgid "update_permission"
msgstr "can be updated by"
@@ -4057,3 +4045,15 @@
msgid "you should probably delete that property"
msgstr ""
+
+#~ msgid "add_perm"
+#~ msgstr "add permission"
+
+#~ msgid "delete_perm"
+#~ msgstr "delete permission"
+
+#~ msgid "read_perm"
+#~ msgstr "read permission"
+
+#~ msgid "update_perm"
+#~ msgstr "update permission"
--- a/i18n/es.po Thu Sep 23 23:28:58 2010 +0200
+++ b/i18n/es.po Wed Sep 29 16:16:32 2010 +0200
@@ -998,9 +998,6 @@
msgid "add a new permission"
msgstr "Agregar una autorización"
-msgid "add_perm"
-msgstr "Agregado"
-
# subject and object forms for each relation type
# (no object form for final relation types)
msgid "add_permission"
@@ -1932,9 +1929,6 @@
msgid "delete this relation"
msgstr "Eliminar esta relación"
-msgid "delete_perm"
-msgstr "Eliminar"
-
msgid "delete_permission"
msgstr "Permiso de eliminar"
@@ -3202,9 +3196,6 @@
msgid "read"
msgstr "Lectura"
-msgid "read_perm"
-msgstr "Lectura"
-
msgid "read_permission"
msgstr "Permiso de lectura"
@@ -3913,9 +3904,6 @@
msgid "update"
msgstr "Modificación"
-msgid "update_perm"
-msgstr "Permiso de Modificar"
-
msgid "update_permission"
msgstr "Puede ser modificado por"
@@ -4198,6 +4186,12 @@
msgid "you should probably delete that property"
msgstr "DeberÃa probablamente suprimir esta propriedad"
+#~ msgid "add_perm"
+#~ msgstr "Agregado"
+
+#~ msgid "delete_perm"
+#~ msgstr "Eliminar"
+
#~ msgid "edition"
#~ msgstr "Edición"
@@ -4206,3 +4200,9 @@
#~ msgid "personnal informations"
#~ msgstr "Información personal"
+
+#~ msgid "read_perm"
+#~ msgstr "Lectura"
+
+#~ msgid "update_perm"
+#~ msgstr "Permiso de Modificar"
--- a/i18n/fr.po Thu Sep 23 23:28:58 2010 +0200
+++ b/i18n/fr.po Wed Sep 29 16:16:32 2010 +0200
@@ -996,9 +996,6 @@
msgid "add a new permission"
msgstr "ajouter une permission"
-msgid "add_perm"
-msgstr "ajout"
-
# subject and object forms for each relation type
# (no object form for final relation types)
msgid "add_permission"
@@ -1930,9 +1927,6 @@
msgid "delete this relation"
msgstr "supprimer cette relation"
-msgid "delete_perm"
-msgstr "suppression"
-
msgid "delete_permission"
msgstr "permission de supprimer"
@@ -3202,9 +3196,6 @@
msgid "read"
msgstr "lecture"
-msgid "read_perm"
-msgstr "lecture"
-
msgid "read_permission"
msgstr "permission de lire"
@@ -3914,9 +3905,6 @@
msgid "update"
msgstr "modification"
-msgid "update_perm"
-msgstr "modification"
-
msgid "update_permission"
msgstr "permission de modification"
@@ -4198,6 +4186,12 @@
msgid "you should probably delete that property"
msgstr "vous devriez probablement supprimer cette propriété"
+#~ msgid "add_perm"
+#~ msgstr "ajout"
+
+#~ msgid "delete_perm"
+#~ msgstr "suppression"
+
#~ msgid "edition"
#~ msgstr "édition"
@@ -4207,5 +4201,11 @@
#~ msgid "personnal informations"
#~ msgstr "informations personnelles"
+#~ msgid "read_perm"
+#~ msgstr "lecture"
+
+#~ msgid "update_perm"
+#~ msgstr "modification"
+
#~ msgid "yams type, rdf type or mime type of the object"
#~ msgstr "type yams, vocabulaire rdf ou type mime de l'objet"
--- a/i18n/static-messages.pot Thu Sep 23 23:28:58 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-msgid "read_perm"
-msgstr ""
-
-msgid "add_perm"
-msgstr ""
-
-msgid "update_perm"
-msgstr ""
-
-msgid "delete_perm"
-msgstr ""
--- a/migration.py Thu Sep 23 23:28:58 2010 +0200
+++ b/migration.py Wed Sep 29 16:16:32 2010 +0200
@@ -129,7 +129,8 @@
return object.__getattribute__(self, name)
except AttributeError:
cmd = 'cmd_%s' % name
- if hasattr(self, cmd):
+ # search self.__class__ to avoid infinite recursion
+ if hasattr(self.__class__, cmd):
meth = getattr(self, cmd)
return lambda *args, **kwargs: self.interact(args, kwargs,
meth=meth)
--- a/selectors.py Thu Sep 23 23:28:58 2010 +0200
+++ b/selectors.py Wed Sep 29 16:16:32 2010 +0200
@@ -194,6 +194,7 @@
import logging
from warnings import warn
+from operator import eq
from logilab.common.deprecation import class_renamed
from logilab.common.compat import all, any
@@ -530,17 +531,26 @@
class multi_lines_rset(Selector):
- """If `nb` is specified, return 1 if the result set has exactly `nb` row of
- result. Else (`nb` is None), return 1 if the result set contains *at least*
+ """Return 1 if the operator expression matches between `num` elements
+ in the result set and the `expected` value if defined.
+
+ By default, multi_lines_rset(expected) matches equality expression:
+ `nb` row(s) in result set equals to expected value
+ But, you can perform richer comparisons by overriding default operator:
+ multi_lines_rset(expected, operator.gt)
+
+ If `expected` is None, return 1 if the result set contains *at least*
two rows.
+ If rset is None, return 0.
"""
- def __init__(self, nb=None):
- self.expected = nb
+ def __init__(self, expected=None, operator=eq):
+ self.expected = expected
+ self.operator = operator
def match_expected(self, num):
if self.expected is None:
return num > 1
- return num == self.expected
+ return self.operator(num, self.expected)
@lltrace
def __call__(self, cls, req, rset=None, **kwargs):
@@ -1039,12 +1049,12 @@
return self.score_entity(kwargs['entity'])
if rset is None:
return 0
- user = req.user
- action = self.action
if row is None:
score = 0
need_local_check = []
geteschema = req.vreg.schema.eschema
+ user = req.user
+ action = self.action
for etype in rset.column_types(0):
if etype in BASE_TYPES:
return 0
@@ -1061,9 +1071,11 @@
if need_local_check:
# check local role for entities of necessary types
for i, row in enumerate(rset):
- if not rset.description[i][0] in need_local_check:
+ if not rset.description[i][col] in need_local_check:
continue
- if not self.score(req, rset, i, col):
+ # micro-optimisation instead of calling self.score(req,
+ # rset, i, col): rset may be large
+ if not rset.get_entity(i, col).cw_has_perm(action):
return 0
score += 1
return score
--- a/server/hook.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/hook.py Wed Sep 29 16:16:32 2010 +0200
@@ -60,6 +60,11 @@
.. _`database trigger`: http://en.wikipedia.org/wiki/Database_trigger
+.. hint::
+
+ It is a good practice to write unit tests for each hook. See an example in
+ :ref:`hook_test`
+
Operations
~~~~~~~~~~
@@ -402,7 +407,7 @@
class MyHook(Hook):
__regid__ = 'whatever'
- __select__ = Hook.__select__ & implements('Person')
+ __select__ = Hook.__select__ & is_instance('Person')
else your hooks will be called madly, whatever the event.
"""
@@ -490,6 +495,8 @@
This hook ensure that when one of the watched relation is added, the
`main_rtype` relation is added to the target entity of the relation.
+ Notice there are no default behaviour defined when a watched relation is
+ deleted, you'll have to handle this by yourself.
You usually want to use the :class:`match_rtype_sets` selector on concret
classes.
--- a/server/querier.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/querier.py Wed Sep 29 16:16:32 2010 +0200
@@ -32,8 +32,8 @@
from rql.nodes import (Relation, VariableRef, Constant, SubQuery, Function,
Exists, Not)
-from cubicweb import Unauthorized, QueryError, UnknownEid, typed_eid
-from cubicweb import server
+from cubicweb import ValidationError, Unauthorized, QueryError, UnknownEid
+from cubicweb import server, typed_eid
from cubicweb.rset import ResultSet
from cubicweb.server.utils import cleanup_solutions
@@ -702,15 +702,9 @@
# execute the plan
try:
results = plan.execute()
- except Unauthorized:
- # XXX this could be done in security's after_add_relation hooks
- # since it's actually realy only needed there (other relations
- # security is done *before* actual changes, and add/update entity
- # security is done after changes but in an operation, and exception
- # generated in operation's events properly generate a rollback on
- # the session). Even though, this is done here for a better
- # consistency: getting an Unauthorized exception means the
- # transaction has been rollbacked
+ except (Unauthorized, ValidationError):
+ # getting an Unauthorized/ValidationError exception means the
+ # transaction must been rollbacked
#
# notes:
# * we should not reset the pool here, since we don't want the
--- a/server/serverctl.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/serverctl.py Wed Sep 29 16:16:32 2010 +0200
@@ -501,7 +501,7 @@
passwdmsg='new password for %s' % adminlogin)
try:
cursor.execute("UPDATE cw_CWUser SET cw_upassword=%(p)s WHERE cw_login=%(l)s",
- {'p': crypt_password(passwd), 'l': adminlogin})
+ {'p': buffer(crypt_password(passwd)), 'l': adminlogin})
sconfig = Configuration(options=USER_OPTIONS)
sconfig['login'] = adminlogin
sconfig['password'] = passwd
--- a/server/sources/native.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/sources/native.py Wed Sep 29 16:16:32 2010 +0200
@@ -142,7 +142,11 @@
"""return backend type and a boolean flag if NULL values should be allowed
for a given relation definition
"""
- coltype = y2sql.type_from_constraints(dbhelper, rdef.object,
+ if rdef.object.final:
+ ttype = rdef.object
+ else:
+ ttype = 'Int' # eid type
+ coltype = y2sql.type_from_constraints(dbhelper, ttype,
rdef.constraints, creating=False)
allownull = rdef.cardinality[0] != '1'
return coltype, allownull
--- a/server/test/unittest_fti.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_fti.py Wed Sep 29 16:16:32 2010 +0200
@@ -12,7 +12,7 @@
def setUp(self):
if not socket.gethostname().endswith('.logilab.fr'):
- self.skip('XXX require logilab configuration')
+ self.skipTest('XXX require logilab configuration')
super(PostgresFTITC, self).setUp()
def test_occurence_count(self):
@@ -24,7 +24,7 @@
c3 = req.create_entity('Card', title=u'c2',
content=u'cubicweb cubicweb')
self.commit()
- self.assertEquals(req.execute('Card X ORDERBY FTIRANK(X) DESC WHERE X has_text "cubicweb"').rows,
+ self.assertEqual(req.execute('Card X ORDERBY FTIRANK(X) DESC WHERE X has_text "cubicweb"').rows,
[[c1.eid], [c3.eid], [c2.eid]])
@@ -41,7 +41,7 @@
c3 = req.create_entity('Card', title=u'cubicweb',
content=u'autre chose')
self.commit()
- self.assertEquals(req.execute('Card X ORDERBY FTIRANK(X) DESC WHERE X has_text "cubicweb"').rows,
+ self.assertEqual(req.execute('Card X ORDERBY FTIRANK(X) DESC WHERE X has_text "cubicweb"').rows,
[[c3.eid], [c1.eid], [c2.eid]])
@@ -55,5 +55,5 @@
c2 = req.create_entity('Comment', content=u'cubicweb cubicweb', comments=c1)
c3 = req.create_entity('Comment', content=u'cubicweb cubicweb cubicweb', comments=c1)
self.commit()
- self.assertEquals(req.execute('Any X ORDERBY FTIRANK(X) DESC WHERE X has_text "cubicweb"').rows,
+ self.assertEqual(req.execute('Any X ORDERBY FTIRANK(X) DESC WHERE X has_text "cubicweb"').rows,
[[c1.eid], [c3.eid], [c2.eid]])
--- a/server/test/unittest_hook.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_hook.py Wed Sep 29 16:16:32 2010 +0200
@@ -47,7 +47,7 @@
l1 = hook.LateOperation(session)
l2 = hook.LateOperation(session)
l3 = hook.Operation(session)
- self.assertEquals(session.pending_operations, [l3, l1, l2])
+ self.assertEqual(session.pending_operations, [l3, l1, l2])
@clean_session_ops
def test_single_last_operation(self):
@@ -56,9 +56,9 @@
l1 = hook.LateOperation(session)
l2 = hook.LateOperation(session)
l3 = hook.Operation(session)
- self.assertEquals(session.pending_operations, [l3, l1, l2, l0])
+ self.assertEqual(session.pending_operations, [l3, l1, l2, l0])
l4 = hook.SingleLastOperation(session)
- self.assertEquals(session.pending_operations, [l3, l1, l2, l4])
+ self.assertEqual(session.pending_operations, [l3, l1, l2, l4])
@clean_session_ops
def test_global_operation_order(self):
@@ -70,7 +70,7 @@
op3 = syncschema.MemSchemaNotifyChanges(session)
op4 = integrity._DelayedDeleteOp(session)
op5 = integrity._CheckORelationOp(session)
- self.assertEquals(session.pending_operations, [op1, op2, op4, op5, op3])
+ self.assertEqual(session.pending_operations, [op1, op2, op4, op5, op3])
class HookCalled(Exception): pass
@@ -102,19 +102,19 @@
class _Hook(hook.Hook):
events = ('before_add_entiti',)
ex = self.assertRaises(Exception, self.o.register, _Hook)
- self.assertEquals(str(ex), 'bad event before_add_entiti on %s._Hook' % __name__)
+ self.assertEqual(str(ex), 'bad event before_add_entiti on %s._Hook' % __name__)
def test_register_bad_hook2(self):
class _Hook(hook.Hook):
events = None
ex = self.assertRaises(Exception, self.o.register, _Hook)
- self.assertEquals(str(ex), 'bad .events attribute None on %s._Hook' % __name__)
+ self.assertEqual(str(ex), 'bad .events attribute None on %s._Hook' % __name__)
def test_register_bad_hook3(self):
class _Hook(hook.Hook):
events = 'before_add_entity'
ex = self.assertRaises(Exception, self.o.register, _Hook)
- self.assertEquals(str(ex), 'bad event b on %s._Hook' % __name__)
+ self.assertEqual(str(ex), 'bad event b on %s._Hook' % __name__)
def test_call_hook(self):
self.o.register(AddAnyHook)
@@ -138,17 +138,17 @@
def test_startup_shutdown(self):
import hooks # cubicweb/server/test/data/hooks.py
- self.assertEquals(hooks.CALLED_EVENTS['server_startup'], True)
+ self.assertEqual(hooks.CALLED_EVENTS['server_startup'], True)
# don't actually call repository.shutdown !
self.repo.hm.call_hooks('server_shutdown', repo=self.repo)
- self.assertEquals(hooks.CALLED_EVENTS['server_shutdown'], True)
+ self.assertEqual(hooks.CALLED_EVENTS['server_shutdown'], True)
def test_session_open_close(self):
import hooks # cubicweb/server/test/data/hooks.py
cnx = self.login('anon')
- self.assertEquals(hooks.CALLED_EVENTS['session_open'], 'anon')
+ self.assertEqual(hooks.CALLED_EVENTS['session_open'], 'anon')
cnx.close()
- self.assertEquals(hooks.CALLED_EVENTS['session_close'], 'anon')
+ self.assertEqual(hooks.CALLED_EVENTS['session_close'], 'anon')
# class RelationHookTC(TestCase):
@@ -162,30 +162,30 @@
# """make sure before_xxx_relation hooks are called directly"""
# self.o.register(self._before_relation_hook,
# 'before_add_relation', 'concerne')
-# self.assertEquals(self.called, [])
+# self.assertEqual(self.called, [])
# self.o.call_hooks('before_add_relation', 'concerne', 'USER',
# 1, 'concerne', 2)
-# self.assertEquals(self.called, [(1, 'concerne', 2)])
+# self.assertEqual(self.called, [(1, 'concerne', 2)])
# def test_after_add_relation(self):
# """make sure after_xxx_relation hooks are deferred"""
# self.o.register(self._after_relation_hook,
# 'after_add_relation', 'concerne')
-# self.assertEquals(self.called, [])
+# self.assertEqual(self.called, [])
# self.o.call_hooks('after_add_relation', 'concerne', 'USER',
# 1, 'concerne', 2)
# self.o.call_hooks('after_add_relation', 'concerne', 'USER',
# 3, 'concerne', 4)
-# self.assertEquals(self.called, [(1, 'concerne', 2), (3, 'concerne', 4)])
+# self.assertEqual(self.called, [(1, 'concerne', 2), (3, 'concerne', 4)])
# def test_before_delete_relation(self):
# """make sure before_xxx_relation hooks are called directly"""
# self.o.register(self._before_relation_hook,
# 'before_delete_relation', 'concerne')
-# self.assertEquals(self.called, [])
+# self.assertEqual(self.called, [])
# self.o.call_hooks('before_delete_relation', 'concerne', 'USER',
# 1, 'concerne', 2)
-# self.assertEquals(self.called, [(1, 'concerne', 2)])
+# self.assertEqual(self.called, [(1, 'concerne', 2)])
# def test_after_delete_relation(self):
# """make sure after_xxx_relation hooks are deferred"""
@@ -195,7 +195,7 @@
# 1, 'concerne', 2)
# self.o.call_hooks('after_delete_relation', 'concerne', 'USER',
# 3, 'concerne', 4)
-# self.assertEquals(self.called, [(1, 'concerne', 2), (3, 'concerne', 4)])
+# self.assertEqual(self.called, [(1, 'concerne', 2), (3, 'concerne', 4)])
# def _before_relation_hook(self, pool, subject, r_type, object):
--- a/server/test/unittest_ldapuser.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_ldapuser.py Wed Sep 29 16:16:32 2010 +0200
@@ -92,19 +92,19 @@
def test_base(self):
# check a known one
e = self.sexecute('CWUser X WHERE X login %(login)s', {'login': SYT}).get_entity(0, 0)
- self.assertEquals(e.login, SYT)
+ self.assertEqual(e.login, SYT)
e.complete()
- self.assertEquals(e.creation_date, None)
- self.assertEquals(e.modification_date, None)
- self.assertEquals(e.firstname, None)
- self.assertEquals(e.surname, None)
- self.assertEquals(e.in_group[0].name, 'users')
- self.assertEquals(e.owned_by[0].login, SYT)
- self.assertEquals(e.created_by, ())
- self.assertEquals(e.primary_email[0].address, 'Sylvain Thenault')
+ self.assertEqual(e.creation_date, None)
+ self.assertEqual(e.modification_date, None)
+ self.assertEqual(e.firstname, None)
+ self.assertEqual(e.surname, None)
+ self.assertEqual(e.in_group[0].name, 'users')
+ self.assertEqual(e.owned_by[0].login, SYT)
+ self.assertEqual(e.created_by, ())
+ self.assertEqual(e.primary_email[0].address, 'Sylvain Thenault')
# email content should be indexed on the user
rset = self.sexecute('CWUser X WHERE X has_text "thenault"')
- self.assertEquals(rset.rows, [[e.eid]])
+ self.assertEqual(rset.rows, [[e.eid]])
def test_not(self):
eid = self.sexecute('CWUser X WHERE X login %(login)s', {'login': SYT})[0][0]
@@ -117,16 +117,16 @@
aeid = self.sexecute('CWUser X WHERE X login %(login)s', {'login': ADIM})[0][0]
rset = self.sexecute('CWUser X, Y WHERE X login %(syt)s, Y login %(adim)s',
{'syt': SYT, 'adim': ADIM})
- self.assertEquals(rset.rows, [[seid, aeid]])
+ self.assertEqual(rset.rows, [[seid, aeid]])
rset = self.sexecute('Any X,Y,L WHERE X login L, X login %(syt)s, Y login %(adim)s',
{'syt': SYT, 'adim': ADIM})
- self.assertEquals(rset.rows, [[seid, aeid, SYT]])
+ self.assertEqual(rset.rows, [[seid, aeid, SYT]])
def test_in(self):
seid = self.sexecute('CWUser X WHERE X login %(login)s', {'login': SYT})[0][0]
aeid = self.sexecute('CWUser X WHERE X login %(login)s', {'login': ADIM})[0][0]
rset = self.sexecute('Any X,L ORDERBY L WHERE X login IN("%s", "%s"), X login L' % (SYT, ADIM))
- self.assertEquals(rset.rows, [[aeid, ADIM], [seid, SYT]])
+ self.assertEqual(rset.rows, [[aeid, ADIM], [seid, SYT]])
def test_relations(self):
eid = self.sexecute('CWUser X WHERE X login %(login)s', {'login': SYT})[0][0]
@@ -144,28 +144,28 @@
def test_upper(self):
eid = self.sexecute('CWUser X WHERE X login %(login)s', {'login': SYT})[0][0]
rset = self.sexecute('Any UPPER(L) WHERE X eid %s, X login L' % eid)
- self.assertEquals(rset[0][0], SYT.upper())
+ self.assertEqual(rset[0][0], SYT.upper())
def test_unknown_attr(self):
eid = self.sexecute('CWUser X WHERE X login %(login)s', {'login': SYT})[0][0]
rset = self.sexecute('Any L,C,M WHERE X eid %s, X login L, '
'X creation_date C, X modification_date M' % eid)
- self.assertEquals(rset[0][0], SYT)
- self.assertEquals(rset[0][1], None)
- self.assertEquals(rset[0][2], None)
+ self.assertEqual(rset[0][0], SYT)
+ self.assertEqual(rset[0][1], None)
+ self.assertEqual(rset[0][2], None)
def test_sort(self):
logins = [l for l, in self.sexecute('Any L ORDERBY L WHERE X login L')]
- self.assertEquals(logins, sorted(logins))
+ self.assertEqual(logins, sorted(logins))
def test_lower_sort(self):
logins = [l for l, in self.sexecute('Any L ORDERBY lower(L) WHERE X login L')]
- self.assertEquals(logins, sorted(logins))
+ self.assertEqual(logins, sorted(logins))
def test_or(self):
rset = self.sexecute('DISTINCT Any X WHERE X login %(login)s OR (X in_group G, G name "managers")',
{'login': SYT})
- self.assertEquals(len(rset), 2, rset.rows) # syt + admin
+ self.assertEqual(len(rset), 2, rset.rows) # syt + admin
def test_nonregr_set_owned_by(self):
# test that when a user coming from ldap is triggering a transition
@@ -173,7 +173,7 @@
self.sexecute('SET X in_group G WHERE X login %(syt)s, G name "managers"', {'syt': SYT})
self.commit()
syt = self.sexecute('CWUser X WHERE X login %(login)s', {'login': SYT}).get_entity(0, 0)
- self.assertEquals([g.name for g in syt.in_group], ['managers', 'users'])
+ self.assertEqual([g.name for g in syt.in_group], ['managers', 'users'])
self.patch_authenticate()
cnx = self.login(SYT, password='dummypassword')
cu = cnx.cursor()
@@ -183,15 +183,15 @@
try:
cnx.commit()
adim.clear_all_caches()
- self.assertEquals(adim.in_state[0].name, 'deactivated')
+ self.assertEqual(adim.in_state[0].name, 'deactivated')
trinfo = iworkflowable.latest_trinfo()
- self.assertEquals(trinfo.owned_by[0].login, SYT)
+ self.assertEqual(trinfo.owned_by[0].login, SYT)
# select from_state to skip the user's creation TrInfo
rset = self.sexecute('Any U ORDERBY D DESC WHERE WF wf_info_for X,'
'WF creation_date D, WF from_state FS,'
'WF owned_by U?, X eid %(x)s',
{'x': adim.eid})
- self.assertEquals(rset.rows, [[syt.eid]])
+ self.assertEqual(rset.rows, [[syt.eid]])
finally:
# restore db state
self.restore_connection()
@@ -213,14 +213,14 @@
self.sexecute('SET U in_group G WHERE G name ~= "bougloup%", U login "admin"')
self.sexecute('SET U in_group G WHERE G name = "bougloup1", U login %(syt)s', {'syt': SYT})
rset = self.sexecute('Any L,SN ORDERBY L WHERE X in_state S, S name SN, X login L, EXISTS(X in_group G, G name ~= "bougloup%")')
- self.assertEquals(rset.rows, [['admin', 'activated'], [SYT, 'activated']])
+ self.assertEqual(rset.rows, [['admin', 'activated'], [SYT, 'activated']])
def test_exists2(self):
self.create_user('comme')
self.create_user('cochon')
self.sexecute('SET X copain Y WHERE X login "comme", Y login "cochon"')
rset = self.sexecute('Any GN ORDERBY GN WHERE X in_group G, G name GN, (G name "managers" OR EXISTS(X copain T, T login in ("comme", "cochon")))')
- self.assertEquals(rset.rows, [['managers'], ['users']])
+ self.assertEqual(rset.rows, [['managers'], ['users']])
def test_exists3(self):
self.create_user('comme')
@@ -230,7 +230,7 @@
self.sexecute('SET X copain Y WHERE X login %(syt)s, Y login "cochon"', {'syt': SYT})
self.failUnless(self.sexecute('Any X, Y WHERE X copain Y, X login %(syt)s, Y login "cochon"', {'syt': SYT}))
rset = self.sexecute('Any GN,L WHERE X in_group G, X login L, G name GN, G name "managers" OR EXISTS(X copain T, T login in ("comme", "cochon"))')
- self.assertEquals(sorted(rset.rows), [['managers', 'admin'], ['users', 'comme'], ['users', SYT]])
+ self.assertEqual(sorted(rset.rows), [['managers', 'admin'], ['users', 'comme'], ['users', SYT]])
def test_exists4(self):
self.create_user('comme')
@@ -252,7 +252,7 @@
all = self.sexecute('Any GN, L WHERE X in_group G, X login L, G name GN')
all.rows.remove(['users', 'comme'])
all.rows.remove(['users', SYT])
- self.assertEquals(sorted(rset.rows), sorted(all.rows))
+ self.assertEqual(sorted(rset.rows), sorted(all.rows))
def test_exists5(self):
self.create_user('comme')
@@ -265,25 +265,25 @@
rset= self.sexecute('Any L WHERE X login L, '
'EXISTS(X copain T, T login in ("comme", "cochon")) AND '
'NOT EXISTS(X copain T2, T2 login "billy")')
- self.assertEquals(sorted(rset.rows), [['cochon'], [SYT]])
+ self.assertEqual(sorted(rset.rows), [['cochon'], [SYT]])
rset= self.sexecute('Any GN,L WHERE X in_group G, X login L, G name GN, '
'EXISTS(X copain T, T login in ("comme", "cochon")) AND '
'NOT EXISTS(X copain T2, T2 login "billy")')
- self.assertEquals(sorted(rset.rows), [['guests', 'cochon'],
+ self.assertEqual(sorted(rset.rows), [['guests', 'cochon'],
['users', 'cochon'],
['users', SYT]])
def test_cd_restriction(self):
rset = self.sexecute('CWUser X WHERE X creation_date > "2009-02-01"')
# admin/anon but no ldap user since it doesn't support creation_date
- self.assertEquals(sorted(e.login for e in rset.entities()),
+ self.assertEqual(sorted(e.login for e in rset.entities()),
['admin', 'anon'])
def test_union(self):
afeids = self.sexecute('State X')
ueids = self.sexecute('CWUser X')
rset = self.sexecute('(Any X WHERE X is State) UNION (Any X WHERE X is CWUser)')
- self.assertEquals(sorted(r[0] for r in rset.rows),
+ self.assertEqual(sorted(r[0] for r in rset.rows),
sorted(r[0] for r in afeids + ueids))
def _init_security_test(self):
@@ -294,23 +294,23 @@
def test_security1(self):
cu = self._init_security_test()
rset = cu.execute('CWUser X WHERE X login %(login)s', {'login': SYT})
- self.assertEquals(rset.rows, [])
+ self.assertEqual(rset.rows, [])
rset = cu.execute('Any X WHERE X login "iaminguestsgrouponly"')
- self.assertEquals(len(rset.rows), 1)
+ self.assertEqual(len(rset.rows), 1)
def test_security2(self):
cu = self._init_security_test()
rset = cu.execute('Any X WHERE X has_text %(syt)s', {'syt': SYT})
- self.assertEquals(rset.rows, [])
+ self.assertEqual(rset.rows, [])
rset = cu.execute('Any X WHERE X has_text "iaminguestsgrouponly"')
- self.assertEquals(len(rset.rows), 1)
+ self.assertEqual(len(rset.rows), 1)
def test_security3(self):
cu = self._init_security_test()
rset = cu.execute('Any F WHERE X has_text %(syt)s, X firstname F', {'syt': SYT})
- self.assertEquals(rset.rows, [])
+ self.assertEqual(rset.rows, [])
rset = cu.execute('Any F WHERE X has_text "iaminguestsgrouponly", X firstname F')
- self.assertEquals(rset.rows, [[None]])
+ self.assertEqual(rset.rows, [[None]])
def test_nonregr1(self):
self.sexecute('Any X,AA ORDERBY AA DESC WHERE E eid %(x)s, E owned_by X, '
@@ -351,34 +351,34 @@
def test_count(self):
trfunc = GlobTrFunc('count', 0)
res = trfunc.apply([[1], [2], [3], [4]])
- self.assertEquals(res, [[4]])
+ self.assertEqual(res, [[4]])
trfunc = GlobTrFunc('count', 1)
res = trfunc.apply([[1, 2], [2, 4], [3, 6], [1, 5]])
- self.assertEquals(res, [[1, 2], [2, 1], [3, 1]])
+ self.assertEqual(res, [[1, 2], [2, 1], [3, 1]])
def test_sum(self):
trfunc = GlobTrFunc('sum', 0)
res = trfunc.apply([[1], [2], [3], [4]])
- self.assertEquals(res, [[10]])
+ self.assertEqual(res, [[10]])
trfunc = GlobTrFunc('sum', 1)
res = trfunc.apply([[1, 2], [2, 4], [3, 6], [1, 5]])
- self.assertEquals(res, [[1, 7], [2, 4], [3, 6]])
+ self.assertEqual(res, [[1, 7], [2, 4], [3, 6]])
def test_min(self):
trfunc = GlobTrFunc('min', 0)
res = trfunc.apply([[1], [2], [3], [4]])
- self.assertEquals(res, [[1]])
+ self.assertEqual(res, [[1]])
trfunc = GlobTrFunc('min', 1)
res = trfunc.apply([[1, 2], [2, 4], [3, 6], [1, 5]])
- self.assertEquals(res, [[1, 2], [2, 4], [3, 6]])
+ self.assertEqual(res, [[1, 2], [2, 4], [3, 6]])
def test_max(self):
trfunc = GlobTrFunc('max', 0)
res = trfunc.apply([[1], [2], [3], [4]])
- self.assertEquals(res, [[4]])
+ self.assertEqual(res, [[4]])
trfunc = GlobTrFunc('max', 1)
res = trfunc.apply([[1, 2], [2, 4], [3, 6], [1, 5]])
- self.assertEquals(res, [[1, 5], [2, 4], [3, 6]])
+ self.assertEqual(res, [[1, 5], [2, 4], [3, 6]])
# XXX
LDAPUserSourceTC._init_repo()
@@ -405,13 +405,13 @@
def test_base(self):
rqlst = self._prepare('CWUser X WHERE X login "toto"').children[0]
- self.assertEquals(self.o.generate(rqlst, 'X')[1],
+ self.assertEqual(self.o.generate(rqlst, 'X')[1],
'(&(objectClass=top)(objectClass=posixAccount)(uid=toto))')
def test_kwargs(self):
rqlst = self._prepare('CWUser X WHERE X login %(x)s').children[0]
self.o._args = {'x': "toto"}
- self.assertEquals(self.o.generate(rqlst, 'X')[1],
+ self.assertEqual(self.o.generate(rqlst, 'X')[1],
'(&(objectClass=top)(objectClass=posixAccount)(uid=toto))')
def test_get_attr(self):
--- a/server/test/unittest_migractions.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_migractions.py Wed Sep 29 16:16:32 2010 +0200
@@ -84,11 +84,11 @@
'RDEF relation_type RT, RDEF ordernum O, RT name RTN'))
self.mh.cmd_add_attribute('Note', 'whatever')
self.failUnless('whatever' in self.schema)
- self.assertEquals(self.schema['whatever'].subjects(), ('Note',))
- self.assertEquals(self.schema['whatever'].objects(), ('Int',))
- self.assertEquals(self.schema['Note'].default('whatever'), 2)
+ self.assertEqual(self.schema['whatever'].subjects(), ('Note',))
+ self.assertEqual(self.schema['whatever'].objects(), ('Int',))
+ self.assertEqual(self.schema['Note'].default('whatever'), 2)
note = self.execute('Note X').get_entity(0, 0)
- self.assertEquals(note.whatever, 2)
+ self.assertEqual(note.whatever, 2)
orderdict2 = dict(self.mh.rqlexec('Any RTN, O WHERE X name "Note", RDEF from_entity X, '
'RDEF relation_type RT, RDEF ordernum O, RT name RTN'))
whateverorder = migrschema['whatever'].rdef('Note', 'Int').order
@@ -97,7 +97,7 @@
orderdict[k] = v+1
orderdict['whatever'] = whateverorder
self.assertDictEquals(orderdict, orderdict2)
- #self.assertEquals([r.type for r in self.schema['Note'].ordered_relations()],
+ #self.assertEqual([r.type for r in self.schema['Note'].ordered_relations()],
# ['modification_date', 'creation_date', 'owned_by',
# 'eid', 'ecrit_par', 'inline1', 'date', 'type',
# 'whatever', 'date', 'in_basket'])
@@ -110,12 +110,12 @@
self.failIf('shortpara' in self.schema)
self.mh.cmd_add_attribute('Note', 'shortpara')
self.failUnless('shortpara' in self.schema)
- self.assertEquals(self.schema['shortpara'].subjects(), ('Note', ))
- self.assertEquals(self.schema['shortpara'].objects(), ('String', ))
+ self.assertEqual(self.schema['shortpara'].subjects(), ('Note', ))
+ self.assertEqual(self.schema['shortpara'].objects(), ('String', ))
# test created column is actually a varchar(64)
notesql = self.mh.sqlexec("SELECT sql FROM sqlite_master WHERE type='table' and name='%sNote'" % SQL_PREFIX)[0][0]
fields = dict(x.strip().split()[:2] for x in notesql.split('(', 1)[1].rsplit(')', 1)[0].split(','))
- self.assertEquals(fields['%sshortpara' % SQL_PREFIX], 'varchar(64)')
+ self.assertEqual(fields['%sshortpara' % SQL_PREFIX], 'varchar(64)')
self.mh.rollback()
def test_add_datetime_with_default_value_attribute(self):
@@ -123,15 +123,15 @@
self.failIf('shortpara' in self.schema)
self.mh.cmd_add_attribute('Note', 'mydate')
self.failUnless('mydate' in self.schema)
- self.assertEquals(self.schema['mydate'].subjects(), ('Note', ))
- self.assertEquals(self.schema['mydate'].objects(), ('Date', ))
+ self.assertEqual(self.schema['mydate'].subjects(), ('Note', ))
+ self.assertEqual(self.schema['mydate'].objects(), ('Date', ))
testdate = date(2005, 12, 13)
eid1 = self.mh.rqlexec('INSERT Note N')[0][0]
eid2 = self.mh.rqlexec('INSERT Note N: N mydate %(mydate)s', {'mydate' : testdate})[0][0]
d1 = self.mh.rqlexec('Any D WHERE X eid %(x)s, X mydate D', {'x': eid1})[0][0]
d2 = self.mh.rqlexec('Any D WHERE X eid %(x)s, X mydate D', {'x': eid2})[0][0]
- self.assertEquals(d1, date.today())
- self.assertEquals(d2, testdate)
+ self.assertEqual(d1, date.today())
+ self.assertEqual(d2, testdate)
self.mh.rollback()
def test_drop_chosen_constraints_ctxmanager(self):
@@ -175,10 +175,10 @@
for etype in ('Personne', 'Email'):
s1 = self.mh.rqlexec('Any N WHERE WF workflow_of ET, ET name "%s", WF name N' %
etype)[0][0]
- self.assertEquals(s1, "foo")
+ self.assertEqual(s1, "foo")
s1 = self.mh.rqlexec('Any N WHERE ET default_workflow WF, ET name "%s", WF name N' %
etype)[0][0]
- self.assertEquals(s1, "foo")
+ self.assertEqual(s1, "foo")
def test_add_entity_type(self):
self.failIf('Folder2' in self.schema)
@@ -189,18 +189,18 @@
self.failUnless('filed_under2' in self.schema)
self.failUnless(self.execute('CWRType X WHERE X name "filed_under2"'))
self.schema.rebuild_infered_relations()
- self.assertEquals(sorted(str(rs) for rs in self.schema['Folder2'].subject_relations()),
+ self.assertEqual(sorted(str(rs) for rs in self.schema['Folder2'].subject_relations()),
['created_by', 'creation_date', 'cwuri',
'description', 'description_format',
'eid',
'filed_under2', 'has_text',
'identity', 'in_basket', 'is', 'is_instance_of',
'modification_date', 'name', 'owned_by'])
- self.assertEquals([str(rs) for rs in self.schema['Folder2'].object_relations()],
+ self.assertEqual([str(rs) for rs in self.schema['Folder2'].object_relations()],
['filed_under2', 'identity'])
- self.assertEquals(sorted(str(e) for e in self.schema['filed_under2'].subjects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['filed_under2'].subjects()),
sorted(str(e) for e in self.schema.entities() if not e.final))
- self.assertEquals(self.schema['filed_under2'].objects(), ('Folder2',))
+ self.assertEqual(self.schema['filed_under2'].objects(), ('Folder2',))
eschema = self.schema.eschema('Folder2')
for cstr in eschema.rdef('name').constraints:
self.failUnless(hasattr(cstr, 'eid'))
@@ -227,22 +227,22 @@
self.mh.cmd_add_relation_type('filed_under2')
self.schema.rebuild_infered_relations()
self.failUnless('filed_under2' in self.schema)
- self.assertEquals(sorted(str(e) for e in self.schema['filed_under2'].subjects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['filed_under2'].subjects()),
sorted(str(e) for e in self.schema.entities() if not e.final))
- self.assertEquals(self.schema['filed_under2'].objects(), ('Folder2',))
+ self.assertEqual(self.schema['filed_under2'].objects(), ('Folder2',))
self.mh.cmd_drop_relation_type('filed_under2')
self.failIf('filed_under2' in self.schema)
def test_add_relation_definition_nortype(self):
self.mh.cmd_add_relation_definition('Personne', 'concerne2', 'Affaire')
- self.assertEquals(self.schema['concerne2'].subjects(),
+ self.assertEqual(self.schema['concerne2'].subjects(),
('Personne',))
- self.assertEquals(self.schema['concerne2'].objects(),
+ self.assertEqual(self.schema['concerne2'].objects(),
('Affaire', ))
- self.assertEquals(self.schema['concerne2'].rdef('Personne', 'Affaire').cardinality,
+ self.assertEqual(self.schema['concerne2'].rdef('Personne', 'Affaire').cardinality,
'1*')
self.mh.cmd_add_relation_definition('Personne', 'concerne2', 'Note')
- self.assertEquals(sorted(self.schema['concerne2'].objects()), ['Affaire', 'Note'])
+ self.assertEqual(sorted(self.schema['concerne2'].objects()), ['Affaire', 'Note'])
self.mh.create_entity('Personne', nom=u'tot')
self.mh.create_entity('Affaire')
self.mh.rqlexec('SET X concerne2 Y WHERE X is Personne, Y is Affaire')
@@ -253,59 +253,59 @@
self.failIf('concerne2' in self.schema)
def test_drop_relation_definition_existant_rtype(self):
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].subjects()),
['Affaire', 'Personne'])
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].objects()),
['Affaire', 'Division', 'Note', 'Societe', 'SubDivision'])
self.mh.cmd_drop_relation_definition('Personne', 'concerne', 'Affaire')
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].subjects()),
['Affaire'])
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].objects()),
['Division', 'Note', 'Societe', 'SubDivision'])
self.mh.cmd_add_relation_definition('Personne', 'concerne', 'Affaire')
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].subjects()),
['Affaire', 'Personne'])
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].objects()),
['Affaire', 'Division', 'Note', 'Societe', 'SubDivision'])
# trick: overwrite self.maxeid to avoid deletion of just reintroduced types
self.maxeid = self.execute('Any MAX(X)')[0][0]
def test_drop_relation_definition_with_specialization(self):
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].subjects()),
['Affaire', 'Personne'])
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].objects()),
['Affaire', 'Division', 'Note', 'Societe', 'SubDivision'])
self.mh.cmd_drop_relation_definition('Affaire', 'concerne', 'Societe')
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].subjects()),
['Affaire', 'Personne'])
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].objects()),
['Affaire', 'Division', 'Note', 'SubDivision'])
self.schema.rebuild_infered_relations() # need to be explicitly called once everything is in place
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].objects()),
['Affaire', 'Note'])
self.mh.cmd_add_relation_definition('Affaire', 'concerne', 'Societe')
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].subjects()),
['Affaire', 'Personne'])
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].objects()),
['Affaire', 'Note', 'Societe'])
self.schema.rebuild_infered_relations() # need to be explicitly called once everything is in place
- self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()),
+ self.assertEqual(sorted(str(e) for e in self.schema['concerne'].objects()),
['Affaire', 'Division', 'Note', 'Societe', 'SubDivision'])
# trick: overwrite self.maxeid to avoid deletion of just reintroduced types
self.maxeid = self.execute('Any MAX(X)')[0][0]
def test_rename_relation(self):
- self.skip('implement me')
+ self.skipTest('implement me')
def test_change_relation_props_non_final(self):
rschema = self.schema['concerne']
card = rschema.rdef('Affaire', 'Societe').cardinality
- self.assertEquals(card, '**')
+ self.assertEqual(card, '**')
try:
self.mh.cmd_change_relation_props('Affaire', 'concerne', 'Societe',
cardinality='?*')
card = rschema.rdef('Affaire', 'Societe').cardinality
- self.assertEquals(card, '?*')
+ self.assertEqual(card, '?*')
finally:
self.mh.cmd_change_relation_props('Affaire', 'concerne', 'Societe',
cardinality='**')
@@ -313,12 +313,12 @@
def test_change_relation_props_final(self):
rschema = self.schema['adel']
card = rschema.rdef('Personne', 'String').fulltextindexed
- self.assertEquals(card, False)
+ self.assertEqual(card, False)
try:
self.mh.cmd_change_relation_props('Personne', 'adel', 'String',
fulltextindexed=True)
card = rschema.rdef('Personne', 'String').fulltextindexed
- self.assertEquals(card, True)
+ self.assertEqual(card, True)
finally:
self.mh.cmd_change_relation_props('Personne', 'adel', 'String',
fulltextindexed=False)
@@ -338,11 +338,11 @@
self.mh.cmd_sync_schema_props_perms(commit=False)
- self.assertEquals(cursor.execute('Any D WHERE X name "Personne", X description D')[0][0],
+ self.assertEqual(cursor.execute('Any D WHERE X name "Personne", X description D')[0][0],
'blabla bla')
- self.assertEquals(cursor.execute('Any D WHERE X name "titre", X description D')[0][0],
+ self.assertEqual(cursor.execute('Any D WHERE X name "titre", X description D')[0][0],
'usually a title')
- self.assertEquals(cursor.execute('Any D WHERE X relation_type RT, RT name "titre",'
+ self.assertEqual(cursor.execute('Any D WHERE X relation_type RT, RT name "titre",'
'X from_entity FE, FE name "Personne",'
'X description D')[0][0],
'title for this person')
@@ -353,29 +353,29 @@
expected = [u'nom', u'prenom', u'sexe', u'promo', u'ass', u'adel', u'titre',
u'web', u'tel', u'fax', u'datenaiss', u'test', 'description', u'firstname',
u'creation_date', 'cwuri', u'modification_date']
- self.assertEquals(rinorder, expected)
+ self.assertEqual(rinorder, expected)
# test permissions synchronization ####################################
# new rql expr to add note entity
eexpr = self._erqlexpr_entity('add', 'Note')
- self.assertEquals(eexpr.expression,
+ self.assertEqual(eexpr.expression,
'X ecrit_part PE, U in_group G, '
'PE require_permission P, P name "add_note", P require_group G')
- self.assertEquals([et.name for et in eexpr.reverse_add_permission], ['Note'])
- self.assertEquals(eexpr.reverse_read_permission, ())
- self.assertEquals(eexpr.reverse_delete_permission, ())
- self.assertEquals(eexpr.reverse_update_permission, ())
+ self.assertEqual([et.name for et in eexpr.reverse_add_permission], ['Note'])
+ self.assertEqual(eexpr.reverse_read_permission, ())
+ self.assertEqual(eexpr.reverse_delete_permission, ())
+ self.assertEqual(eexpr.reverse_update_permission, ())
# no more rqlexpr to delete and add para attribute
self.failIf(self._rrqlexpr_rset('add', 'para'))
self.failIf(self._rrqlexpr_rset('delete', 'para'))
# new rql expr to add ecrit_par relation
rexpr = self._rrqlexpr_entity('add', 'ecrit_par')
- self.assertEquals(rexpr.expression,
+ self.assertEqual(rexpr.expression,
'O require_permission P, P name "add_note", '
'U in_group G, P require_group G')
- self.assertEquals([rdef.rtype.name for rdef in rexpr.reverse_add_permission], ['ecrit_par'])
- self.assertEquals(rexpr.reverse_read_permission, ())
- self.assertEquals(rexpr.reverse_delete_permission, ())
+ self.assertEqual([rdef.rtype.name for rdef in rexpr.reverse_add_permission], ['ecrit_par'])
+ self.assertEqual(rexpr.reverse_read_permission, ())
+ self.assertEqual(rexpr.reverse_delete_permission, ())
# no more rqlexpr to delete and add travaille relation
self.failIf(self._rrqlexpr_rset('add', 'travaille'))
self.failIf(self._rrqlexpr_rset('delete', 'travaille'))
@@ -386,13 +386,13 @@
self.failIf(self._erqlexpr_rset('read', 'Affaire'))
# rqlexpr to update Affaire entity has been updated
eexpr = self._erqlexpr_entity('update', 'Affaire')
- self.assertEquals(eexpr.expression, 'X concerne S, S owned_by U')
+ self.assertEqual(eexpr.expression, 'X concerne S, S owned_by U')
# no change for rqlexpr to add and delete Affaire entity
- self.assertEquals(len(self._erqlexpr_rset('delete', 'Affaire')), 1)
- self.assertEquals(len(self._erqlexpr_rset('add', 'Affaire')), 1)
+ self.assertEqual(len(self._erqlexpr_rset('delete', 'Affaire')), 1)
+ self.assertEqual(len(self._erqlexpr_rset('add', 'Affaire')), 1)
# no change for rqlexpr to add and delete concerne relation
- self.assertEquals(len(self._rrqlexpr_rset('delete', 'concerne')), len(delete_concerne_rqlexpr))
- self.assertEquals(len(self._rrqlexpr_rset('add', 'concerne')), len(add_concerne_rqlexpr))
+ self.assertEqual(len(self._rrqlexpr_rset('delete', 'concerne')), len(delete_concerne_rqlexpr))
+ self.assertEqual(len(self._rrqlexpr_rset('add', 'concerne')), len(add_concerne_rqlexpr))
# * migrschema involve:
# * 7 rqlexprs deletion (2 in (Affaire read + Societe + travaille) + 1
# in para attribute)
@@ -400,36 +400,36 @@
# * 2 new (Note add, ecrit_par add)
# * 2 implicit new for attributes update_permission (Note.para, Personne.test)
# remaining orphan rql expr which should be deleted at commit (composite relation)
- self.assertEquals(cursor.execute('Any COUNT(X) WHERE X is RQLExpression, '
+ self.assertEqual(cursor.execute('Any COUNT(X) WHERE X is RQLExpression, '
'NOT ET1 read_permission X, NOT ET2 add_permission X, '
'NOT ET3 delete_permission X, NOT ET4 update_permission X')[0][0],
7+1)
# finally
- self.assertEquals(cursor.execute('Any COUNT(X) WHERE X is RQLExpression')[0][0],
+ self.assertEqual(cursor.execute('Any COUNT(X) WHERE X is RQLExpression')[0][0],
nbrqlexpr_start + 1 + 2 + 2)
self.mh.commit()
# unique_together test
self.assertEqual(len(self.schema.eschema('Personne')._unique_together), 1)
- self.assertUnorderedIterableEquals(self.schema.eschema('Personne')._unique_together[0],
+ self.assertItemsEqual(self.schema.eschema('Personne')._unique_together[0],
('nom', 'prenom', 'datenaiss'))
rset = cursor.execute('Any C WHERE C is CWUniqueTogetherConstraint')
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
relations = [r.rtype.name for r in rset.get_entity(0,0).relations]
- self.assertUnorderedIterableEquals(relations, ('nom', 'prenom', 'datenaiss'))
+ self.assertItemsEqual(relations, ('nom', 'prenom', 'datenaiss'))
def _erqlexpr_rset(self, action, ertype):
rql = 'RQLExpression X WHERE ET is CWEType, ET %s_permission X, ET name %%(name)s' % action
return self.mh.session.execute(rql, {'name': ertype})
def _erqlexpr_entity(self, action, ertype):
rset = self._erqlexpr_rset(action, ertype)
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
return rset.get_entity(0, 0)
def _rrqlexpr_rset(self, action, ertype):
rql = 'RQLExpression X WHERE RT is CWRType, RDEF %s_permission X, RT name %%(name)s, RDEF relation_type RT' % action
return self.mh.session.execute(rql, {'name': ertype})
def _rrqlexpr_entity(self, action, ertype):
rset = self._rrqlexpr_rset(action, ertype)
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
return rset.get_entity(0, 0)
def test_set_size_constraint(self):
@@ -447,7 +447,7 @@
def test_add_remove_cube_and_deps(self):
cubes = set(self.config.cubes())
schema = self.repo.schema
- self.assertEquals(sorted((str(s), str(o)) for s, o in schema['see_also'].rdefs.keys()),
+ self.assertEqual(sorted((str(s), str(o)) for s, o in schema['see_also'].rdefs.keys()),
sorted([('EmailThread', 'EmailThread'), ('Folder', 'Folder'),
('Bookmark', 'Bookmark'), ('Bookmark', 'Note'),
('Note', 'Note'), ('Note', 'Bookmark')]))
@@ -462,16 +462,16 @@
for ertype in ('Email', 'EmailThread', 'EmailPart', 'File',
'sender', 'in_thread', 'reply_to', 'data_format'):
self.failIf(ertype in schema, ertype)
- self.assertEquals(sorted(schema['see_also'].rdefs.keys()),
+ self.assertEqual(sorted(schema['see_also'].rdefs.keys()),
sorted([('Folder', 'Folder'),
('Bookmark', 'Bookmark'),
('Bookmark', 'Note'),
('Note', 'Note'),
('Note', 'Bookmark')]))
- self.assertEquals(sorted(schema['see_also'].subjects()), ['Bookmark', 'Folder', 'Note'])
- self.assertEquals(sorted(schema['see_also'].objects()), ['Bookmark', 'Folder', 'Note'])
- self.assertEquals(self.execute('Any X WHERE X pkey "system.version.email"').rowcount, 0)
- self.assertEquals(self.execute('Any X WHERE X pkey "system.version.file"').rowcount, 0)
+ self.assertEqual(sorted(schema['see_also'].subjects()), ['Bookmark', 'Folder', 'Note'])
+ self.assertEqual(sorted(schema['see_also'].objects()), ['Bookmark', 'Folder', 'Note'])
+ self.assertEqual(self.execute('Any X WHERE X pkey "system.version.email"').rowcount, 0)
+ self.assertEqual(self.execute('Any X WHERE X pkey "system.version.file"').rowcount, 0)
except :
import traceback
traceback.print_exc()
@@ -485,19 +485,19 @@
for ertype in ('Email', 'EmailThread', 'EmailPart', 'File',
'sender', 'in_thread', 'reply_to', 'data_format'):
self.failUnless(ertype in schema, ertype)
- self.assertEquals(sorted(schema['see_also'].rdefs.keys()),
+ self.assertEqual(sorted(schema['see_also'].rdefs.keys()),
sorted([('EmailThread', 'EmailThread'), ('Folder', 'Folder'),
('Bookmark', 'Bookmark'),
('Bookmark', 'Note'),
('Note', 'Note'),
('Note', 'Bookmark')]))
- self.assertEquals(sorted(schema['see_also'].subjects()), ['Bookmark', 'EmailThread', 'Folder', 'Note'])
- self.assertEquals(sorted(schema['see_also'].objects()), ['Bookmark', 'EmailThread', 'Folder', 'Note'])
+ self.assertEqual(sorted(schema['see_also'].subjects()), ['Bookmark', 'EmailThread', 'Folder', 'Note'])
+ self.assertEqual(sorted(schema['see_also'].objects()), ['Bookmark', 'EmailThread', 'Folder', 'Note'])
from cubes.email.__pkginfo__ import version as email_version
from cubes.file.__pkginfo__ import version as file_version
- self.assertEquals(self.execute('Any V WHERE X value V, X pkey "system.version.email"')[0][0],
+ self.assertEqual(self.execute('Any V WHERE X value V, X pkey "system.version.email"')[0][0],
email_version)
- self.assertEquals(self.execute('Any V WHERE X value V, X pkey "system.version.file"')[0][0],
+ self.assertEqual(self.execute('Any V WHERE X value V, X pkey "system.version.file"')[0][0],
file_version)
# trick: overwrite self.maxeid to avoid deletion of just reintroduced
# types (and their associated tables!)
@@ -535,19 +535,19 @@
def test_remove_dep_cube(self):
ex = self.assertRaises(ConfigurationError, self.mh.cmd_remove_cube, 'file')
- self.assertEquals(str(ex), "can't remove cube file, used as a dependency")
+ self.assertEqual(str(ex), "can't remove cube file, used as a dependency")
def test_introduce_base_class(self):
self.mh.cmd_add_entity_type('Para')
self.mh.repo.schema.rebuild_infered_relations()
- self.assertEquals(sorted(et.type for et in self.schema['Para'].specialized_by()),
+ self.assertEqual(sorted(et.type for et in self.schema['Para'].specialized_by()),
['Note'])
- self.assertEquals(self.schema['Note'].specializes().type, 'Para')
+ self.assertEqual(self.schema['Note'].specializes().type, 'Para')
self.mh.cmd_add_entity_type('Text')
self.mh.repo.schema.rebuild_infered_relations()
- self.assertEquals(sorted(et.type for et in self.schema['Para'].specialized_by()),
+ self.assertEqual(sorted(et.type for et in self.schema['Para'].specialized_by()),
['Note', 'Text'])
- self.assertEquals(self.schema['Text'].specializes().type, 'Para')
+ self.assertEqual(self.schema['Text'].specializes().type, 'Para')
# test columns have been actually added
text = self.execute('INSERT Text X: X para "hip", X summary "hop", X newattr "momo"').get_entity(0, 0)
note = self.execute('INSERT Note X: X para "hip", X shortpara "hop", X newattr "momo", X unique_id "x"').get_entity(0, 0)
@@ -574,10 +574,10 @@
self.commit()
finally:
self.session.data['rebuild-infered'] = False
- self.assertEquals(sorted(et.type for et in self.schema['Para'].specialized_by()),
+ self.assertEqual(sorted(et.type for et in self.schema['Para'].specialized_by()),
[])
- self.assertEquals(self.schema['Note'].specializes(), None)
- self.assertEquals(self.schema['Text'].specializes(), None)
+ self.assertEqual(self.schema['Note'].specializes(), None)
+ self.assertEqual(self.schema['Text'].specializes(), None)
def test_add_symmetric_relation_type(self):
--- a/server/test/unittest_msplanner.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_msplanner.py Wed Sep 29 16:16:32 2010 +0200
@@ -141,8 +141,8 @@
for var in sourcevars.keys():
solindices = sourcevars.pop(var)
sourcevars[var._ms_table_key()] = solindices
- self.assertEquals(ppi._sourcesterms, sourcesterms)
- self.assertEquals(ppi.needsplit, needsplit)
+ self.assertEqual(ppi._sourcesterms, sourcesterms)
+ self.assertEqual(ppi.needsplit, needsplit)
def test_simple_system_only(self):
@@ -2032,7 +2032,7 @@
# identity relation. BUT I think it's better to leave it as is and to
# explain constraint propagation rules, and so why this should be
# wrapped in exists() if used in multi-source
- self.skip('take a look at me if you wish')
+ self.skipTest('take a look at me if you wish')
self._test('Any B,U,UL GROUPBY B,U,UL WHERE B created_by U?, B is File '
'WITH U,UL BEING (Any U,UL WHERE ME eid %(x)s, (U identity ME '
'OR (EXISTS(U in_group G, G name IN("managers", "staff")))) '
--- a/server/test/unittest_multisources.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_multisources.py Wed Sep 29 16:16:32 2010 +0200
@@ -101,34 +101,34 @@
def test_eid_comp(self):
rset = self.sexecute('Card X WHERE X eid > 1')
- self.assertEquals(len(rset), 4)
+ self.assertEqual(len(rset), 4)
rset = self.sexecute('Any X,T WHERE X title T, X eid > 1')
- self.assertEquals(len(rset), 4)
+ self.assertEqual(len(rset), 4)
def test_metainformation(self):
rset = self.sexecute('Card X ORDERBY T WHERE X title T')
# 2 added to the system source, 2 added to the external source
- self.assertEquals(len(rset), 4)
+ self.assertEqual(len(rset), 4)
# since they are orderd by eid, we know the 3 first one is coming from the system source
# and the others from external source
- self.assertEquals(rset.get_entity(0, 0).cw_metainformation(),
+ self.assertEqual(rset.get_entity(0, 0).cw_metainformation(),
{'source': {'adapter': 'native', 'uri': 'system'},
'type': u'Card', 'extid': None})
externent = rset.get_entity(3, 0)
metainf = externent.cw_metainformation()
- self.assertEquals(metainf['source'], {'adapter': 'pyrorql', 'base-url': 'http://extern.org/', 'uri': 'extern'})
- self.assertEquals(metainf['type'], 'Card')
+ self.assertEqual(metainf['source'], {'adapter': 'pyrorql', 'base-url': 'http://extern.org/', 'uri': 'extern'})
+ self.assertEqual(metainf['type'], 'Card')
self.assert_(metainf['extid'])
etype = self.sexecute('Any ETN WHERE X is ET, ET name ETN, X eid %(x)s',
{'x': externent.eid})[0][0]
- self.assertEquals(etype, 'Card')
+ self.assertEqual(etype, 'Card')
def test_order_limit_offset(self):
rsetbase = self.sexecute('Any W,X ORDERBY W,X WHERE X wikiid W')
- self.assertEquals(len(rsetbase), 4)
- self.assertEquals(sorted(rsetbase.rows), rsetbase.rows)
+ self.assertEqual(len(rsetbase), 4)
+ self.assertEqual(sorted(rsetbase.rows), rsetbase.rows)
rset = self.sexecute('Any W,X ORDERBY W,X LIMIT 2 OFFSET 2 WHERE X wikiid W')
- self.assertEquals(rset.rows, rsetbase.rows[2:4])
+ self.assertEqual(rset.rows, rsetbase.rows[2:4])
def test_has_text(self):
self.repo.sources_by_uri['extern'].synchronize(MTIME) # in case fti_update has been run before
@@ -148,9 +148,9 @@
cu = cnx.cursor()
rset = cu.execute('Any X WHERE X has_text "card"')
# 5: 4 card + 1 readable affaire
- self.assertEquals(len(rset), 5, zip(rset.rows, rset.description))
+ self.assertEqual(len(rset), 5, zip(rset.rows, rset.description))
rset = cu.execute('Any X ORDERBY FTIRANK(X) WHERE X has_text "card"')
- self.assertEquals(len(rset), 5, zip(rset.rows, rset.description))
+ self.assertEqual(len(rset), 5, zip(rset.rows, rset.description))
Connection_close(cnx.cnx) # cnx is a TestCaseConnectionProxy
def test_synchronization(self):
@@ -178,14 +178,14 @@
affeid = self.sexecute('Affaire X WHERE X ref "AFFREF"')[0][0]
rset = self.sexecute('Any X,AA,AB WHERE E eid %(x)s, E in_state X, X name AA, X modification_date AB',
{'x': affeid})
- self.assertEquals(len(rset), 1)
- self.assertEquals(rset[0][1], "pitetre")
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset[0][1], "pitetre")
def test_simplifiable_var_2(self):
affeid = self.sexecute('Affaire X WHERE X ref "AFFREF"')[0][0]
rset = self.sexecute('Any E WHERE E eid %(x)s, E in_state S, NOT S name "moved"',
{'x': affeid, 'u': self.session.user.eid})
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
def test_sort_func(self):
self.sexecute('Affaire X ORDERBY DUMB_SORT(RF) WHERE X ref RF')
@@ -197,31 +197,31 @@
iec1 = self.repo.extid2eid(self.repo.sources_by_uri['extern'], str(self.ec1),
'Card', self.session)
rset = self.sexecute('Any X WHERE X eid IN (%s, %s)' % (iec1, self.ic1))
- self.assertEquals(sorted(r[0] for r in rset.rows), sorted([iec1, self.ic1]))
+ self.assertEqual(sorted(r[0] for r in rset.rows), sorted([iec1, self.ic1]))
def test_greater_eid(self):
rset = self.sexecute('Any X WHERE X eid > %s' % (self.ic1 - 1))
- self.assertEquals(len(rset.rows), 2) # self.ic1 and self.ic2
+ self.assertEqual(len(rset.rows), 2) # self.ic1 and self.ic2
cu = cnx2.cursor()
ec2 = cu.execute('INSERT Card X: X title "glup"')[0][0]
cnx2.commit()
# 'X eid > something' should not trigger discovery
rset = self.sexecute('Any X WHERE X eid > %s' % (self.ic1 - 1))
- self.assertEquals(len(rset.rows), 2)
+ self.assertEqual(len(rset.rows), 2)
# trigger discovery using another query
crset = self.sexecute('Card X WHERE X title "glup"')
- self.assertEquals(len(crset.rows), 1)
+ self.assertEqual(len(crset.rows), 1)
rset = self.sexecute('Any X WHERE X eid > %s' % (self.ic1 - 1))
- self.assertEquals(len(rset.rows), 3)
+ self.assertEqual(len(rset.rows), 3)
rset = self.sexecute('Any MAX(X)')
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(rset.rows[0][0], crset[0][0])
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(rset.rows[0][0], crset[0][0])
def test_attr_unification_1(self):
n1 = self.sexecute('INSERT Note X: X type "AFFREF"')[0][0]
n2 = self.sexecute('INSERT Note X: X type "AFFREU"')[0][0]
rset = self.sexecute('Any X,Y WHERE X is Note, Y is Affaire, X type T, Y ref T')
- self.assertEquals(len(rset), 1, rset.rows)
+ self.assertEqual(len(rset), 1, rset.rows)
def test_attr_unification_2(self):
cu = cnx2.cursor()
@@ -230,7 +230,7 @@
try:
c1 = self.sexecute('INSERT Card C: C title "AFFREF"')[0][0]
rset = self.sexecute('Any X,Y WHERE X is Card, Y is Affaire, X title T, Y ref T')
- self.assertEquals(len(rset), 2, rset.rows)
+ self.assertEqual(len(rset), 2, rset.rows)
finally:
cu.execute('DELETE Card X WHERE X eid %(x)s', {'x': ec2})
cnx2.commit()
@@ -247,26 +247,26 @@
afeids = self.sexecute('Affaire X')
ueids = self.sexecute('CWUser X')
rset = self.sexecute('(Any X WHERE X is Affaire) UNION (Any X WHERE X is CWUser)')
- self.assertEquals(sorted(r[0] for r in rset.rows),
+ self.assertEqual(sorted(r[0] for r in rset.rows),
sorted(r[0] for r in afeids + ueids))
def test_subquery1(self):
rsetbase = self.sexecute('Any W,X WITH W,X BEING (Any W,X ORDERBY W,X WHERE X wikiid W)')
- self.assertEquals(len(rsetbase), 4)
- self.assertEquals(sorted(rsetbase.rows), rsetbase.rows)
+ self.assertEqual(len(rsetbase), 4)
+ self.assertEqual(sorted(rsetbase.rows), rsetbase.rows)
rset = self.sexecute('Any W,X LIMIT 2 OFFSET 2 WITH W,X BEING (Any W,X ORDERBY W,X WHERE X wikiid W)')
- self.assertEquals(rset.rows, rsetbase.rows[2:4])
+ self.assertEqual(rset.rows, rsetbase.rows[2:4])
rset = self.sexecute('Any W,X ORDERBY W,X LIMIT 2 OFFSET 2 WITH W,X BEING (Any W,X WHERE X wikiid W)')
- self.assertEquals(rset.rows, rsetbase.rows[2:4])
+ self.assertEqual(rset.rows, rsetbase.rows[2:4])
rset = self.sexecute('Any W,X WITH W,X BEING (Any W,X ORDERBY W,X LIMIT 2 OFFSET 2 WHERE X wikiid W)')
- self.assertEquals(rset.rows, rsetbase.rows[2:4])
+ self.assertEqual(rset.rows, rsetbase.rows[2:4])
def test_subquery2(self):
affeid = self.sexecute('Affaire X WHERE X ref "AFFREF"')[0][0]
rset = self.sexecute('Any X,AA,AB WITH X,AA,AB BEING (Any X,AA,AB WHERE E eid %(x)s, E in_state X, X name AA, X modification_date AB)',
{'x': affeid})
- self.assertEquals(len(rset), 1)
- self.assertEquals(rset[0][1], "pitetre")
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset[0][1], "pitetre")
def test_not_relation(self):
states = set(tuple(x) for x in self.sexecute('Any S,SN WHERE S is State, S name SN'))
@@ -275,22 +275,22 @@
states.remove((userstate.eid, userstate.name))
notstates = set(tuple(x) for x in self.sexecute('Any S,SN WHERE S is State, S name SN, NOT X in_state S, X eid %(x)s',
{'x': self.session.user.eid}))
- self.assertSetEquals(notstates, states)
+ self.assertSetEqual(notstates, states)
aff1 = self.sexecute('Any X WHERE X is Affaire, X ref "AFFREF"')[0][0]
aff1stateeid, aff1statename = self.sexecute('Any S,SN WHERE X eid %(x)s, X in_state S, S name SN', {'x': aff1})[0]
- self.assertEquals(aff1statename, 'pitetre')
+ self.assertEqual(aff1statename, 'pitetre')
states.add((userstate.eid, userstate.name))
states.remove((aff1stateeid, aff1statename))
notstates = set(tuple(x) for x in self.sexecute('Any S,SN WHERE S is State, S name SN, NOT X in_state S, X eid %(x)s',
{'x': aff1}))
- self.assertSetEquals(notstates, states)
+ self.assertSetEqual(notstates, states)
def test_absolute_url_base_url(self):
cu = cnx2.cursor()
ceid = cu.execute('INSERT Card X: X title "without wikiid to get eid based url"')[0][0]
cnx2.commit()
lc = self.sexecute('Card X WHERE X title "without wikiid to get eid based url"').get_entity(0, 0)
- self.assertEquals(lc.absolute_url(), 'http://extern.org/card/eid/%s' % ceid)
+ self.assertEqual(lc.absolute_url(), 'http://extern.org/card/eid/%s' % ceid)
cu.execute('DELETE Card X WHERE X eid %(x)s', {'x':ceid})
cnx2.commit()
@@ -299,7 +299,7 @@
ceid = cu.execute('INSERT Card X: X title "without wikiid to get eid based url"')[0][0]
cnx3.commit()
lc = self.sexecute('Card X WHERE X title "without wikiid to get eid based url"').get_entity(0, 0)
- self.assertEquals(lc.absolute_url(), 'http://testing.fr/cubicweb/card/eid/%s' % lc.eid)
+ self.assertEqual(lc.absolute_url(), 'http://testing.fr/cubicweb/card/eid/%s' % lc.eid)
cu.execute('DELETE Card X WHERE X eid %(x)s', {'x':ceid})
cnx3.commit()
@@ -315,8 +315,8 @@
treid = iworkflowable.latest_trinfo().eid
rset = self.sexecute('Any X ORDERBY D DESC WHERE E eid %(x)s, E wf_info_for X, X modification_date D',
{'x': treid})
- self.assertEquals(len(rset), 1)
- self.assertEquals(rset.rows[0], [self.session.user.eid])
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.rows[0], [self.session.user.eid])
def test_nonregr3(self):
self.sexecute('DELETE Card X WHERE X eid %(x)s, NOT X multisource_inlined_rel Y', {'x': self.ic1})
--- a/server/test/unittest_querier.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_querier.py Wed Sep 29 16:16:32 2010 +0200
@@ -57,7 +57,7 @@
class MakeSchemaTC(TestCase):
def test_known_values(self):
solution = {'A': 'String', 'B': 'CWUser'}
- self.assertEquals(make_schema((Variable('A'), Variable('B')), solution,
+ self.assertEqual(make_schema((Variable('A'), Variable('B')), solution,
'table0', TYPEMAP),
('C0 text,C1 integer', {'A': 'table0.C0', 'B': 'table0.C1'}))
@@ -84,7 +84,7 @@
def test_preprocess_1(self):
reid = self.execute('Any X WHERE X is CWRType, X name "owned_by"')[0][0]
rqlst = self._prepare('Any COUNT(RDEF) WHERE RDEF relation_type X, X eid %(x)s', {'x': reid})
- self.assertEquals(rqlst.solutions, [{'RDEF': 'CWAttribute'}, {'RDEF': 'CWRelation'}])
+ self.assertEqual(rqlst.solutions, [{'RDEF': 'CWAttribute'}, {'RDEF': 'CWRelation'}])
def test_preprocess_2(self):
teid = self.execute("INSERT Tag X: X name 'tag'")[0][0]
@@ -94,7 +94,7 @@
rqlst = self._prepare('Any X WHERE E eid %(x)s, E tags X', {'x': teid})
# the query may be optimized, should keep only one solution
# (any one, etype will be discarded)
- self.assertEquals(len(rqlst.solutions), 1)
+ self.assertEqual(len(rqlst.solutions), 1)
def test_preprocess_security(self):
plan = self._prepare_plan('Any ETN,COUNT(X) GROUPBY ETN '
@@ -102,24 +102,24 @@
plan.session = self.user_groups_session('users')
union = plan.rqlst
plan.preprocess(union)
- self.assertEquals(len(union.children), 1)
- self.assertEquals(len(union.children[0].with_), 1)
+ self.assertEqual(len(union.children), 1)
+ self.assertEqual(len(union.children[0].with_), 1)
subq = union.children[0].with_[0].query
- self.assertEquals(len(subq.children), 3)
- self.assertEquals([t.as_string() for t in union.children[0].selection],
+ self.assertEqual(len(subq.children), 3)
+ self.assertEqual([t.as_string() for t in union.children[0].selection],
['ETN','COUNT(X)'])
- self.assertEquals([t.as_string() for t in union.children[0].groupby],
+ self.assertEqual([t.as_string() for t in union.children[0].groupby],
['ETN'])
partrqls = sorted(((rqlst.as_string(), rqlst.solutions) for rqlst in subq.children))
rql, solutions = partrqls[0]
- self.assertEquals(rql,
+ self.assertEqual(rql,
'Any ETN,X WHERE X is ET, ET name ETN, (EXISTS(X owned_by %(B)s))'
' OR ((((EXISTS(D concerne C?, C owned_by %(B)s, X identity D, C is Division, D is Affaire))'
' OR (EXISTS(H concerne G?, G owned_by %(B)s, G is SubDivision, X identity H, H is Affaire)))'
' OR (EXISTS(I concerne F?, F owned_by %(B)s, F is Societe, X identity I, I is Affaire)))'
' OR (EXISTS(J concerne E?, E owned_by %(B)s, E is Note, X identity J, J is Affaire)))'
', ET is CWEType, X is Affaire')
- self.assertEquals(solutions, [{'C': 'Division',
+ self.assertEqual(solutions, [{'C': 'Division',
'D': 'Affaire',
'E': 'Note',
'F': 'Societe',
@@ -130,8 +130,8 @@
'X': 'Affaire',
'ET': 'CWEType', 'ETN': 'String'}])
rql, solutions = partrqls[1]
- self.assertEquals(rql, 'Any ETN,X WHERE X is ET, ET name ETN, ET is CWEType, X is IN(BaseTransition, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, CWUniqueTogetherConstraint, CWUser, Card, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Note, Personne, RQLExpression, Societe, State, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)')
- self.assertListEquals(sorted(solutions),
+ self.assertEqual(rql, 'Any ETN,X WHERE X is ET, ET name ETN, ET is CWEType, X is IN(BaseTransition, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, CWUniqueTogetherConstraint, CWUser, Card, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Note, Personne, RQLExpression, Societe, State, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)')
+ self.assertListEqual(sorted(solutions),
sorted([{'X': 'BaseTransition', 'ETN': 'String', 'ET': 'CWEType'},
{'X': 'Bookmark', 'ETN': 'String', 'ET': 'CWEType'},
{'X': 'Card', 'ETN': 'String', 'ET': 'CWEType'},
@@ -169,10 +169,10 @@
{'X': 'Workflow', 'ETN': 'String', 'ET': 'CWEType'},
{'X': 'WorkflowTransition', 'ETN': 'String', 'ET': 'CWEType'}]))
rql, solutions = partrqls[2]
- self.assertEquals(rql,
+ self.assertEqual(rql,
'Any ETN,X WHERE X is ET, ET name ETN, EXISTS(X owned_by %(C)s), '
'ET is CWEType, X is Basket')
- self.assertEquals(solutions, [{'ET': 'CWEType',
+ self.assertEqual(solutions, [{'ET': 'CWEType',
'X': 'Basket',
'ETN': 'String',
}])
@@ -182,45 +182,45 @@
plan.session = self.user_groups_session('users')
union = plan.rqlst
plan.preprocess(union)
- self.assertEquals(len(union.children), 1)
- self.assertEquals(len(union.children[0].with_), 1)
+ self.assertEqual(len(union.children), 1)
+ self.assertEqual(len(union.children[0].with_), 1)
subq = union.children[0].with_[0].query
- self.assertEquals(len(subq.children), 3)
- self.assertEquals([t.as_string() for t in union.children[0].selection],
+ self.assertEqual(len(subq.children), 3)
+ self.assertEqual([t.as_string() for t in union.children[0].selection],
['MAX(X)'])
def test_preprocess_nonregr(self):
rqlst = self._prepare('Any S ORDERBY SI WHERE NOT S ecrit_par O, S para SI')
- self.assertEquals(len(rqlst.solutions), 1)
+ self.assertEqual(len(rqlst.solutions), 1)
def test_build_description(self):
# should return an empty result set
rset = self.execute('Any X WHERE X eid %(x)s', {'x': self.session.user.eid})
- self.assertEquals(rset.description[0][0], 'CWUser')
+ self.assertEqual(rset.description[0][0], 'CWUser')
rset = self.execute('Any 1')
- self.assertEquals(rset.description[0][0], 'Int')
+ self.assertEqual(rset.description[0][0], 'Int')
rset = self.execute('Any TRUE')
- self.assertEquals(rset.description[0][0], 'Boolean')
+ self.assertEqual(rset.description[0][0], 'Boolean')
rset = self.execute('Any "hop"')
- self.assertEquals(rset.description[0][0], 'String')
+ self.assertEqual(rset.description[0][0], 'String')
rset = self.execute('Any TODAY')
- self.assertEquals(rset.description[0][0], 'Date')
+ self.assertEqual(rset.description[0][0], 'Date')
rset = self.execute('Any NOW')
- self.assertEquals(rset.description[0][0], 'Datetime')
+ self.assertEqual(rset.description[0][0], 'Datetime')
rset = self.execute('Any %(x)s', {'x': 1})
- self.assertEquals(rset.description[0][0], 'Int')
+ self.assertEqual(rset.description[0][0], 'Int')
rset = self.execute('Any %(x)s', {'x': 1L})
- self.assertEquals(rset.description[0][0], 'Int')
+ self.assertEqual(rset.description[0][0], 'Int')
rset = self.execute('Any %(x)s', {'x': True})
- self.assertEquals(rset.description[0][0], 'Boolean')
+ self.assertEqual(rset.description[0][0], 'Boolean')
rset = self.execute('Any %(x)s', {'x': 1.0})
- self.assertEquals(rset.description[0][0], 'Float')
+ self.assertEqual(rset.description[0][0], 'Float')
rset = self.execute('Any %(x)s', {'x': datetime.now()})
- self.assertEquals(rset.description[0][0], 'Datetime')
+ self.assertEqual(rset.description[0][0], 'Datetime')
rset = self.execute('Any %(x)s', {'x': 'str'})
- self.assertEquals(rset.description[0][0], 'String')
+ self.assertEqual(rset.description[0][0], 'String')
rset = self.execute('Any %(x)s', {'x': u'str'})
- self.assertEquals(rset.description[0][0], 'String')
+ self.assertEqual(rset.description[0][0], 'String')
class QuerierTC(BaseQuerierTC):
@@ -244,46 +244,46 @@
{'data': Binary("xxx")})[0][0]
fdata = self.execute('Any D WHERE X data D, X eid %(x)s', {'x': feid})[0][0]
self.assertIsInstance(fdata, Binary)
- self.assertEquals(fdata.getvalue(), 'xxx')
+ self.assertEqual(fdata.getvalue(), 'xxx')
# selection queries tests #################################################
def test_select_1(self):
rset = self.execute('Any X ORDERBY X WHERE X is CWGroup')
result, descr = rset.rows, rset.description
- self.assertEquals(tuplify(result), [(1,), (2,), (3,), (4,)])
- self.assertEquals(descr, [('CWGroup',), ('CWGroup',), ('CWGroup',), ('CWGroup',)])
+ self.assertEqual(tuplify(result), [(1,), (2,), (3,), (4,)])
+ self.assertEqual(descr, [('CWGroup',), ('CWGroup',), ('CWGroup',), ('CWGroup',)])
def test_select_2(self):
rset = self.execute('Any X ORDERBY N WHERE X is CWGroup, X name N')
- self.assertEquals(tuplify(rset.rows), [(1,), (2,), (3,), (4,)])
- self.assertEquals(rset.description, [('CWGroup',), ('CWGroup',), ('CWGroup',), ('CWGroup',)])
+ self.assertEqual(tuplify(rset.rows), [(1,), (2,), (3,), (4,)])
+ self.assertEqual(rset.description, [('CWGroup',), ('CWGroup',), ('CWGroup',), ('CWGroup',)])
rset = self.execute('Any X ORDERBY N DESC WHERE X is CWGroup, X name N')
- self.assertEquals(tuplify(rset.rows), [(4,), (3,), (2,), (1,)])
+ self.assertEqual(tuplify(rset.rows), [(4,), (3,), (2,), (1,)])
def test_select_3(self):
rset = self.execute('Any N GROUPBY N WHERE X is CWGroup, X name N')
result, descr = rset.rows, rset.description
result.sort()
- self.assertEquals(tuplify(result), [('guests',), ('managers',), ('owners',), ('users',)])
- self.assertEquals(descr, [('String',), ('String',), ('String',), ('String',)])
+ self.assertEqual(tuplify(result), [('guests',), ('managers',), ('owners',), ('users',)])
+ self.assertEqual(descr, [('String',), ('String',), ('String',), ('String',)])
def test_select_is(self):
rset = self.execute('Any X, TN ORDERBY TN LIMIT 10 WHERE X is T, T name TN')
result, descr = rset.rows, rset.description
- self.assertEquals(result[0][1], descr[0][0])
+ self.assertEqual(result[0][1], descr[0][0])
def test_select_is_aggr(self):
rset = self.execute('Any TN, COUNT(X) GROUPBY TN ORDERBY 2 DESC WHERE X is T, T name TN')
result, descr = rset.rows, rset.description
- self.assertEquals(descr[0][0], 'String')
- self.assertEquals(descr[0][1], 'Int')
- self.assertEquals(result[0][0], 'CWRelation') # XXX may change as schema evolve
+ self.assertEqual(descr[0][0], 'String')
+ self.assertEqual(descr[0][1], 'Int')
+ self.assertEqual(result[0][0], 'CWRelation') # XXX may change as schema evolve
def test_select_groupby_orderby(self):
rset = self.execute('Any N GROUPBY N ORDERBY N WHERE X is CWGroup, X name N')
- self.assertEquals(tuplify(rset.rows), [('guests',), ('managers',), ('owners',), ('users',)])
- self.assertEquals(rset.description, [('String',), ('String',), ('String',), ('String',)])
+ self.assertEqual(tuplify(rset.rows), [('guests',), ('managers',), ('owners',), ('users',)])
+ self.assertEqual(rset.description, [('String',), ('String',), ('String',), ('String',)])
def test_select_complex_groupby(self):
rset = self.execute('Any N GROUPBY N WHERE X name N')
@@ -295,20 +295,20 @@
def test_select_complex_orderby(self):
rset1 = self.execute('Any N ORDERBY N WHERE X name N')
- self.assertEquals(sorted(rset1.rows), rset1.rows)
+ self.assertEqual(sorted(rset1.rows), rset1.rows)
rset = self.execute('Any N ORDERBY N LIMIT 5 OFFSET 1 WHERE X name N')
- self.assertEquals(rset.rows[0][0], rset1.rows[1][0])
- self.assertEquals(len(rset), 5)
+ self.assertEqual(rset.rows[0][0], rset1.rows[1][0])
+ self.assertEqual(len(rset), 5)
def test_select_5(self):
rset = self.execute('Any X, TMP ORDERBY TMP WHERE X name TMP, X is CWGroup')
- self.assertEquals(tuplify(rset.rows), [(1, 'guests',), (2, 'managers',), (3, 'owners',), (4, 'users',)])
- self.assertEquals(rset.description, [('CWGroup', 'String',), ('CWGroup', 'String',), ('CWGroup', 'String',), ('CWGroup', 'String',)])
+ self.assertEqual(tuplify(rset.rows), [(1, 'guests',), (2, 'managers',), (3, 'owners',), (4, 'users',)])
+ self.assertEqual(rset.description, [('CWGroup', 'String',), ('CWGroup', 'String',), ('CWGroup', 'String',), ('CWGroup', 'String',)])
def test_select_6(self):
self.execute("INSERT Personne X: X nom 'bidule'")[0]
rset = self.execute('Any Y where X name TMP, Y nom in (TMP, "bidule")')
- #self.assertEquals(rset.description, [('Personne',), ('Personne',)])
+ #self.assertEqual(rset.description, [('Personne',), ('Personne',)])
self.assert_(('Personne',) in rset.description)
rset = self.execute('DISTINCT Any Y where X name TMP, Y nom in (TMP, "bidule")')
self.assert_(('Personne',) in rset.description)
@@ -317,17 +317,17 @@
peid = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
seid = self.execute("INSERT Societe X: X nom 'chouette'")[0][0]
rset = self.execute('Personne X WHERE NOT X nom "bidule"')
- self.assertEquals(len(rset.rows), 0, rset.rows)
+ self.assertEqual(len(rset.rows), 0, rset.rows)
rset = self.execute('Personne X WHERE NOT X nom "bid"')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
self.execute("SET P travaille S WHERE P nom 'bidule', S nom 'chouette'")
rset = self.execute('Personne X WHERE NOT X travaille S')
- self.assertEquals(len(rset.rows), 0, rset.rows)
+ self.assertEqual(len(rset.rows), 0, rset.rows)
def test_select_is_in(self):
self.execute("INSERT Personne X: X nom 'bidule'")
self.execute("INSERT Societe X: X nom 'chouette'")
- self.assertEquals(len(self.execute("Any X WHERE X is IN (Personne, Societe)")),
+ self.assertEqual(len(self.execute("Any X WHERE X is IN (Personne, Societe)")),
2)
def test_select_not_rel(self):
@@ -336,9 +336,9 @@
self.execute("INSERT Personne X: X nom 'autre'")
self.execute("SET P travaille S WHERE P nom 'bidule', S nom 'chouette'")
rset = self.execute('Personne X WHERE NOT X travaille S')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
rset = self.execute('Personne X WHERE NOT X travaille S, S nom "chouette"')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_nonregr_inlined(self):
self.execute("INSERT Note X: X para 'bidule'")
@@ -347,15 +347,15 @@
self.execute("SET X ecrit_par P WHERE X para 'bidule', P nom 'chouette'")
rset = self.execute('Any U,T ORDERBY T DESC WHERE U is CWUser, '
'N ecrit_par U, N type T')#, {'x': self.ueid})
- self.assertEquals(len(rset.rows), 0)
+ self.assertEqual(len(rset.rows), 0)
def test_select_nonregr_edition_not(self):
groupeids = set((1, 2, 3))
groupreadperms = set(r[0] for r in self.execute('Any Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), X read_permission Y'))
rset = self.execute('DISTINCT Any Y WHERE X is CWEType, X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
- self.assertEquals(sorted(r[0] for r in rset.rows), sorted(groupeids - groupreadperms))
+ self.assertEqual(sorted(r[0] for r in rset.rows), sorted(groupeids - groupreadperms))
rset = self.execute('DISTINCT Any Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
- self.assertEquals(sorted(r[0] for r in rset.rows), sorted(groupeids - groupreadperms))
+ self.assertEqual(sorted(r[0] for r in rset.rows), sorted(groupeids - groupreadperms))
def test_select_outer_join(self):
peid1 = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
@@ -363,27 +363,27 @@
seid1 = self.execute("INSERT Societe X: X nom 'chouette'")[0][0]
seid2 = self.execute("INSERT Societe X: X nom 'chouetos'")[0][0]
rset = self.execute('Any X,S ORDERBY X WHERE X travaille S?')
- self.assertEquals(rset.rows, [[peid1, None], [peid2, None]])
+ self.assertEqual(rset.rows, [[peid1, None], [peid2, None]])
self.execute("SET P travaille S WHERE P nom 'bidule', S nom 'chouette'")
rset = self.execute('Any X,S ORDERBY X WHERE X travaille S?')
- self.assertEquals(rset.rows, [[peid1, seid1], [peid2, None]])
+ self.assertEqual(rset.rows, [[peid1, seid1], [peid2, None]])
rset = self.execute('Any S,X ORDERBY S WHERE X? travaille S')
- self.assertEquals(rset.rows, [[seid1, peid1], [seid2, None]])
+ self.assertEqual(rset.rows, [[seid1, peid1], [seid2, None]])
def test_select_outer_join_optimized(self):
peid1 = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
rset = self.execute('Any X WHERE X eid %(x)s, P? connait X', {'x':peid1})
- self.assertEquals(rset.rows, [[peid1]])
+ self.assertEqual(rset.rows, [[peid1]])
rset = self.execute('Any X WHERE X eid %(x)s, X require_permission P?',
{'x':peid1})
- self.assertEquals(rset.rows, [[peid1]])
+ self.assertEqual(rset.rows, [[peid1]])
def test_select_left_outer_join(self):
rset = self.execute('DISTINCT Any G WHERE U? in_group G')
- self.assertEquals(len(rset), 4)
+ self.assertEqual(len(rset), 4)
rset = self.execute('DISTINCT Any G WHERE U? in_group G, U eid %(x)s',
{'x': self.session.user.eid})
- self.assertEquals(len(rset), 4)
+ self.assertEqual(len(rset), 4)
def test_select_ambigous_outer_join(self):
teid = self.execute("INSERT Tag X: X name 'tag'")[0][0]
@@ -395,7 +395,7 @@
self.failUnless(['users', 'tag'] in rset.rows)
self.failUnless(['activated', None] in rset.rows)
rset = self.execute("Any GN,TN ORDERBY GN WHERE T tags G?, T name TN, G name GN")
- self.assertEquals(rset.rows, [[None, 'tagbis'], ['users', 'tag']])
+ self.assertEqual(rset.rows, [[None, 'tagbis'], ['users', 'tag']])
def test_select_not_inline_rel(self):
self.execute("INSERT Personne X: X nom 'bidule'")
@@ -403,7 +403,7 @@
self.execute("INSERT Note X: X type 'b'")
self.execute("SET X ecrit_par Y WHERE X type 'a', Y nom 'bidule'")
rset = self.execute('Note X WHERE NOT X ecrit_par P')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_not_unlinked_multiple_solutions(self):
self.execute("INSERT Personne X: X nom 'bidule'")
@@ -411,7 +411,7 @@
self.execute("INSERT Note X: X type 'b'")
self.execute("SET Y evaluee X WHERE X type 'a', Y nom 'bidule'")
rset = self.execute('Note X WHERE NOT Y evaluee X')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_date_extraction(self):
self.execute("INSERT Personne X: X nom 'foo', X datenaiss %(d)s",
@@ -421,41 +421,41 @@
for funcname, result in test_data:
rset = self.execute('Any %s(D) WHERE X is Personne, X datenaiss D'
% funcname)
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(rset.rows[0][0], result)
- self.assertEquals(rset.description, [('Int',)])
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(rset.rows[0][0], result)
+ self.assertEqual(rset.description, [('Int',)])
def test_select_aggregat_count(self):
rset = self.execute('Any COUNT(X)')
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(len(rset.rows[0]), 1)
- self.assertEquals(rset.description, [('Int',)])
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(len(rset.rows[0]), 1)
+ self.assertEqual(rset.description, [('Int',)])
def test_select_aggregat_sum(self):
rset = self.execute('Any SUM(O) WHERE X ordernum O')
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(len(rset.rows[0]), 1)
- self.assertEquals(rset.description, [('Int',)])
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(len(rset.rows[0]), 1)
+ self.assertEqual(rset.description, [('Int',)])
def test_select_aggregat_min(self):
rset = self.execute('Any MIN(X) WHERE X is Personne')
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(len(rset.rows[0]), 1)
- self.assertEquals(rset.description, [('Personne',)])
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(len(rset.rows[0]), 1)
+ self.assertEqual(rset.description, [('Personne',)])
rset = self.execute('Any MIN(O) WHERE X ordernum O')
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(len(rset.rows[0]), 1)
- self.assertEquals(rset.description, [('Int',)])
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(len(rset.rows[0]), 1)
+ self.assertEqual(rset.description, [('Int',)])
def test_select_aggregat_max(self):
rset = self.execute('Any MAX(X) WHERE X is Personne')
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(len(rset.rows[0]), 1)
- self.assertEquals(rset.description, [('Personne',)])
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(len(rset.rows[0]), 1)
+ self.assertEqual(rset.description, [('Personne',)])
rset = self.execute('Any MAX(O) WHERE X ordernum O')
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(len(rset.rows[0]), 1)
- self.assertEquals(rset.description, [('Int',)])
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(len(rset.rows[0]), 1)
+ self.assertEqual(rset.description, [('Int',)])
def test_select_custom_aggregat_concat_string(self):
rset = self.execute('Any GROUP_CONCAT(N) WHERE X is CWGroup, X name N')
@@ -482,15 +482,15 @@
def test_select_aggregat_sort(self):
rset = self.execute('Any G, COUNT(U) GROUPBY G ORDERBY 2 WHERE U in_group G')
- self.assertEquals(len(rset.rows), 2)
- self.assertEquals(len(rset.rows[0]), 2)
- self.assertEquals(rset.description[0], ('CWGroup', 'Int',))
+ self.assertEqual(len(rset.rows), 2)
+ self.assertEqual(len(rset.rows[0]), 2)
+ self.assertEqual(rset.description[0], ('CWGroup', 'Int',))
def test_select_aggregat_having(self):
rset = self.execute('Any N,COUNT(RDEF) GROUPBY N ORDERBY 2,N '
'WHERE RT name N, RDEF relation_type RT '
'HAVING COUNT(RDEF) > 10')
- self.assertListEquals(rset.rows,
+ self.assertListEqual(rset.rows,
[[u'description_format', 12],
[u'description', 13],
[u'name', 14],
@@ -508,13 +508,13 @@
rset = self.execute('Any U,COUNT(X) GROUPBY U '
'WHERE U eid %(x)s, X owned_by U '
'HAVING COUNT(X) > 10', {'x': self.ueid})
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(rset.rows[0][0], self.ueid)
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(rset.rows[0][0], self.ueid)
def test_select_having_non_aggregat_1(self):
rset = self.execute('Any L WHERE X login L, X creation_date CD '
'HAVING YEAR(CD) = %s' % date.today().year)
- self.assertListEquals(rset.rows,
+ self.assertListEqual(rset.rows,
[[u'admin'],
[u'anon']])
@@ -522,7 +522,7 @@
rset = self.execute('Any L GROUPBY L WHERE X login L, X in_group G, '
'X creation_date CD HAVING YEAR(CD) = %s OR COUNT(G) > 1'
% date.today().year)
- self.assertListEquals(rset.rows,
+ self.assertListEqual(rset.rows,
[[u'admin'],
[u'anon']])
@@ -531,39 +531,46 @@
rset = self.execute('Any X ORDERBY X,D LIMIT 5 WHERE X creation_date D')
result = rset.rows
result.sort()
- self.assertEquals(tuplify(result), [(1,), (2,), (3,), (4,), (5,)])
+ self.assertEqual(tuplify(result), [(1,), (2,), (3,), (4,), (5,)])
def test_select_upper(self):
rset = self.execute('Any X, UPPER(L) ORDERBY L WHERE X is CWUser, X login L')
- self.assertEquals(len(rset.rows), 2)
- self.assertEquals(rset.rows[0][1], 'ADMIN')
- self.assertEquals(rset.description[0], ('CWUser', 'String',))
- self.assertEquals(rset.rows[1][1], 'ANON')
- self.assertEquals(rset.description[1], ('CWUser', 'String',))
+ self.assertEqual(len(rset.rows), 2)
+ self.assertEqual(rset.rows[0][1], 'ADMIN')
+ self.assertEqual(rset.description[0], ('CWUser', 'String',))
+ self.assertEqual(rset.rows[1][1], 'ANON')
+ self.assertEqual(rset.description[1], ('CWUser', 'String',))
eid = rset.rows[0][0]
rset = self.execute('Any UPPER(L) WHERE X eid %s, X login L'%eid)
- self.assertEquals(rset.rows[0][0], 'ADMIN')
- self.assertEquals(rset.description, [('String',)])
+ self.assertEqual(rset.rows[0][0], 'ADMIN')
+ self.assertEqual(rset.description, [('String',)])
def test_select_float_abs(self):
# test positive number
eid = self.execute('INSERT Affaire A: A invoiced %(i)s', {'i': 1.2})[0][0]
rset = self.execute('Any ABS(I) WHERE X eid %(x)s, X invoiced I', {'x': eid})
- self.assertEquals(rset.rows[0][0], 1.2)
+ self.assertEqual(rset.rows[0][0], 1.2)
# test negative number
eid = self.execute('INSERT Affaire A: A invoiced %(i)s', {'i': -1.2})[0][0]
rset = self.execute('Any ABS(I) WHERE X eid %(x)s, X invoiced I', {'x': eid})
- self.assertEquals(rset.rows[0][0], 1.2)
+ self.assertEqual(rset.rows[0][0], 1.2)
def test_select_int_abs(self):
# test positive number
eid = self.execute('INSERT Affaire A: A duration %(d)s', {'d': 12})[0][0]
rset = self.execute('Any ABS(D) WHERE X eid %(x)s, X duration D', {'x': eid})
- self.assertEquals(rset.rows[0][0], 12)
+ self.assertEqual(rset.rows[0][0], 12)
# test negative number
eid = self.execute('INSERT Affaire A: A duration %(d)s', {'d': -12})[0][0]
rset = self.execute('Any ABS(D) WHERE X eid %(x)s, X duration D', {'x': eid})
- self.assertEquals(rset.rows[0][0], 12)
+ self.assertEqual(rset.rows[0][0], 12)
+
+## def test_select_simplified(self):
+## ueid = self.session.user.eid
+## rset = self.execute('Any L WHERE %s login L'%ueid)
+## self.assertEqual(rset.rows[0][0], 'admin')
+## rset = self.execute('Any L WHERE %(x)s login L', {'x':ueid})
+## self.assertEqual(rset.rows[0][0], 'admin')
def test_select_searchable_text_1(self):
rset = self.execute(u"INSERT Personne X: X nom 'bidüle'")
@@ -571,9 +578,9 @@
rset = self.execute("INSERT Societe X: X nom 'chouette'")
self.commit()
rset = self.execute('Any X where X has_text %(text)s', {'text': u'bidüle'})
- self.assertEquals(len(rset.rows), 2, rset.rows)
+ self.assertEqual(len(rset.rows), 2, rset.rows)
rset = self.execute(u'Any N where N has_text "bidüle"')
- self.assertEquals(len(rset.rows), 2, rset.rows)
+ self.assertEqual(len(rset.rows), 2, rset.rows)
biduleeids = [r[0] for r in rset.rows]
rset = self.execute(u'Any N where NOT N has_text "bidüle"')
self.failIf([r[0] for r in rset.rows if r[0] in biduleeids])
@@ -586,7 +593,7 @@
rset = self.execute("INSERT Societe X: X nom 'bidule'")
self.commit()
rset = self.execute('Personne N where N has_text "bidule"')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_searchable_text_3(self):
rset = self.execute("INSERT Personne X: X nom 'bidule', X sexe 'M'")
@@ -594,7 +601,7 @@
rset = self.execute("INSERT Societe X: X nom 'bidule'")
self.commit()
rset = self.execute('Any X where X has_text "bidule" and X sexe "M"')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_multiple_searchable_text(self):
self.execute(u"INSERT Personne X: X nom 'bidüle'")
@@ -605,20 +612,20 @@
{'text': u'bidüle',
'text2': u'chouette',}
)
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_no_descr(self):
rset = self.execute('Any X WHERE X is CWGroup', build_descr=0)
rset.rows.sort()
- self.assertEquals(tuplify(rset.rows), [(1,), (2,), (3,), (4,)])
- self.assertEquals(rset.description, ())
+ self.assertEqual(tuplify(rset.rows), [(1,), (2,), (3,), (4,)])
+ self.assertEqual(rset.description, ())
def test_select_limit_offset(self):
rset = self.execute('CWGroup X ORDERBY N LIMIT 2 WHERE X name N')
- self.assertEquals(tuplify(rset.rows), [(1,), (2,)])
- self.assertEquals(rset.description, [('CWGroup',), ('CWGroup',)])
+ self.assertEqual(tuplify(rset.rows), [(1,), (2,)])
+ self.assertEqual(rset.description, [('CWGroup',), ('CWGroup',)])
rset = self.execute('CWGroup X ORDERBY N LIMIT 2 OFFSET 2 WHERE X name N')
- self.assertEquals(tuplify(rset.rows), [(3,), (4,)])
+ self.assertEqual(tuplify(rset.rows), [(3,), (4,)])
def test_select_symmetric(self):
self.execute("INSERT Personne X: X nom 'machin'")
@@ -628,24 +635,24 @@
self.execute("SET X connait Y WHERE X nom 'chouette', Y nom 'bidule'")
self.execute("SET X connait Y WHERE X nom 'machin', Y nom 'chouette'")
rset = self.execute('Any P where P connait P2')
- self.assertEquals(len(rset.rows), 3, rset.rows)
+ self.assertEqual(len(rset.rows), 3, rset.rows)
rset = self.execute('Any P where NOT P connait P2')
- self.assertEquals(len(rset.rows), 1, rset.rows) # trucmuche
+ self.assertEqual(len(rset.rows), 1, rset.rows) # trucmuche
rset = self.execute('Any P where P connait P2, P2 nom "bidule"')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
rset = self.execute('Any P where P2 connait P, P2 nom "bidule"')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
rset = self.execute('Any P where P connait P2, P2 nom "chouette"')
- self.assertEquals(len(rset.rows), 2, rset.rows)
+ self.assertEqual(len(rset.rows), 2, rset.rows)
rset = self.execute('Any P where P2 connait P, P2 nom "chouette"')
- self.assertEquals(len(rset.rows), 2, rset.rows)
+ self.assertEqual(len(rset.rows), 2, rset.rows)
def test_select_inline(self):
self.execute("INSERT Personne X: X nom 'bidule'")
self.execute("INSERT Note X: X type 'a'")
self.execute("SET X ecrit_par Y WHERE X type 'a', Y nom 'bidule'")
rset = self.execute('Any N where N ecrit_par X, X nom "bidule"')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_creation_date(self):
self.execute("INSERT Personne X: X nom 'bidule'")
@@ -715,13 +722,13 @@
def test_select_explicit_eid(self):
rset = self.execute('Any X,E WHERE X owned_by U, X eid E, U eid %(u)s', {'u': self.session.user.eid})
self.failUnless(rset)
- self.assertEquals(rset.description[0][1], 'Int')
+ self.assertEqual(rset.description[0][1], 'Int')
# def test_select_rewritten_optional(self):
# eid = self.execute("INSERT Affaire X: X sujet 'cool'")[0][0]
# rset = self.execute('Any X WHERE X eid %(x)s, EXISTS(X owned_by U) OR EXISTS(X concerne S?, S owned_by U)',
# {'x': eid}, 'x')
-# self.assertEquals(rset.rows, [[eid]])
+# self.assertEqual(rset.rows, [[eid]])
def test_today_bug(self):
self.execute("INSERT Tag X: X name 'bidule', X creation_date NOW")
@@ -742,14 +749,14 @@
def test_select_boolean(self):
rset = self.execute('Any N WHERE X is CWEType, X name N, X final %(val)s',
{'val': True})
- self.assertEquals(sorted(r[0] for r in rset.rows), ['Boolean', 'Bytes',
+ self.assertEqual(sorted(r[0] for r in rset.rows), ['Boolean', 'Bytes',
'Date', 'Datetime',
'Decimal', 'Float',
'Int', 'Interval',
'Password', 'String',
'Time'])
rset = self.execute('Any N WHERE X is CWEType, X name N, X final TRUE')
- self.assertEquals(sorted(r[0] for r in rset.rows), ['Boolean', 'Bytes',
+ self.assertEqual(sorted(r[0] for r in rset.rows), ['Boolean', 'Bytes',
'Date', 'Datetime',
'Decimal', 'Float',
'Int', 'Interval',
@@ -758,17 +765,17 @@
def test_select_constant(self):
rset = self.execute('Any X, "toto" ORDERBY X WHERE X is CWGroup')
- self.assertEquals(rset.rows,
+ self.assertEqual(rset.rows,
map(list, zip((1,2,3,4), ('toto','toto','toto','toto',))))
self.assertIsInstance(rset[0][1], unicode)
- self.assertEquals(rset.description,
+ self.assertEqual(rset.description,
zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
('String', 'String', 'String', 'String',)))
rset = self.execute('Any X, %(value)s ORDERBY X WHERE X is CWGroup', {'value': 'toto'})
- self.assertEquals(rset.rows,
+ self.assertEqual(rset.rows,
map(list, zip((1,2,3,4), ('toto','toto','toto','toto',))))
self.assertIsInstance(rset[0][1], unicode)
- self.assertEquals(rset.description,
+ self.assertEqual(rset.description,
zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
('String', 'String', 'String', 'String',)))
rset = self.execute('Any X,GN WHERE X is CWUser, G is CWGroup, X login "syt", X in_group G, G name GN')
@@ -779,9 +786,9 @@
' UNION '
'(Any X,N WHERE X name N, X state_of WF, WF workflow_of E, E name %(name)s))',
{'name': 'CWUser'})
- self.assertEquals([x[1] for x in rset.rows],
+ self.assertEqual([x[1] for x in rset.rows],
['activate', 'activated', 'deactivate', 'deactivated'])
- self.assertEquals(rset.description,
+ self.assertEqual(rset.description,
[('Transition', 'String'), ('State', 'String'),
('Transition', 'String'), ('State', 'String')])
@@ -801,13 +808,13 @@
'((Any N,COUNT(X) GROUPBY N WHERE X name N, X is State HAVING COUNT(X)>1)'
' UNION '
'(Any N,COUNT(X) GROUPBY N WHERE X name N, X is Transition HAVING COUNT(X)>1))')
- self.assertEquals(rset.rows, [[u'hop', 2], [u'hop', 2]])
+ self.assertEqual(rset.rows, [[u'hop', 2], [u'hop', 2]])
def test_select_union_selection_with_diff_variables(self):
rset = self.execute('(Any N WHERE X name N, X is State)'
' UNION '
'(Any NN WHERE XX name NN, XX is Transition)')
- self.assertEquals(sorted(r[0] for r in rset.rows),
+ self.assertEqual(sorted(r[0] for r in rset.rows),
['abort', 'activate', 'activated', 'ben non',
'deactivate', 'deactivated', 'done', 'en cours',
'end', 'finie', 'markasdone', 'pitetre', 'redoit',
@@ -820,7 +827,7 @@
' UNION '
'(Any Y WHERE Y eid %(y)s)',
{'x': eid1, 'y': eid2})
- self.assertEquals(rset.description[:], [('CWGroup',), ('CWUser',)])
+ self.assertEqual(rset.description[:], [('CWGroup',), ('CWUser',)])
def test_exists(self):
geid = self.execute("INSERT CWGroup X: X name 'lulufanclub'")[0][0]
@@ -828,15 +835,15 @@
peid = self.execute("INSERT Personne X: X prenom 'lulu', X nom 'petit'")[0][0]
rset = self.execute("Any X WHERE X prenom 'lulu',"
"EXISTS (U in_group G, G name 'lulufanclub' OR G name 'managers');")
- self.assertEquals(rset.rows, [[peid]])
+ self.assertEqual(rset.rows, [[peid]])
def test_identity(self):
eid = self.execute('Any X WHERE X identity Y, Y eid 1')[0][0]
- self.assertEquals(eid, 1)
+ self.assertEqual(eid, 1)
eid = self.execute('Any X WHERE Y identity X, Y eid 1')[0][0]
- self.assertEquals(eid, 1)
+ self.assertEqual(eid, 1)
login = self.execute('Any L WHERE X login "admin", X identity Y, Y login L')[0][0]
- self.assertEquals(login, 'admin')
+ self.assertEqual(login, 'admin')
def test_select_date_mathexp(self):
rset = self.execute('Any X, TODAY - CD WHERE X is CWUser, X creation_date CD')
@@ -852,8 +859,8 @@
rset = self.execute('Any GN, COUNT(X)*100/T GROUPBY GN ORDERBY 2,1'
' WHERE G name GN, X in_group G'
' WITH T BEING (Any COUNT(U) WHERE U is CWUser)')
- self.assertEquals(rset.rows, [[u'guests', 50], [u'managers', 50], [u'users', 100]])
- self.assertEquals(rset.description, [('String', 'Int'), ('String', 'Int'), ('String', 'Int')])
+ self.assertEqual(rset.rows, [[u'guests', 50], [u'managers', 50], [u'users', 100]])
+ self.assertEqual(rset.description, [('String', 'Int'), ('String', 'Int'), ('String', 'Int')])
def test_select_subquery_aggregat_2(self):
expected = self.execute('Any X, 0, COUNT(T) GROUPBY X '
@@ -864,55 +871,55 @@
T? transition_of P, T type "auto"),
P2,E BEING (Any P,COUNT(T) GROUPBY P WHERE P is Workflow, T is Transition,
T? transition_of P, T type "normal")''')
- self.assertEquals(sorted(rset.rows), sorted(expected))
+ self.assertEqual(sorted(rset.rows), sorted(expected))
def test_select_subquery_const(self):
rset = self.execute('Any X WITH X BEING ((Any NULL) UNION (Any "toto"))')
- self.assertEquals(rset.rows, [[None], ['toto']])
- self.assertEquals(rset.description, [(None,), ('String',)])
+ self.assertEqual(rset.rows, [[None], ['toto']])
+ self.assertEqual(rset.description, [(None,), ('String',)])
# insertion queries tests #################################################
def test_insert_is(self):
eid, = self.execute("INSERT Personne X: X nom 'bidule'")[0]
etype, = self.execute("Any TN WHERE X is T, X eid %s, T name TN" % eid)[0]
- self.assertEquals(etype, 'Personne')
+ self.assertEqual(etype, 'Personne')
self.execute("INSERT Personne X: X nom 'managers'")
def test_insert_1(self):
rset = self.execute("INSERT Personne X: X nom 'bidule'")
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(rset.description, [('Personne',)])
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(rset.description, [('Personne',)])
rset = self.execute('Personne X WHERE X nom "bidule"')
self.assert_(rset.rows)
- self.assertEquals(rset.description, [('Personne',)])
+ self.assertEqual(rset.description, [('Personne',)])
def test_insert_1_multiple(self):
self.execute("INSERT Personne X: X nom 'bidule'")
self.execute("INSERT Personne X: X nom 'chouette'")
rset = self.execute("INSERT Societe Y: Y nom N, P travaille Y WHERE P nom N")
- self.assertEquals(len(rset.rows), 2)
- self.assertEquals(rset.description, [('Societe',), ('Societe',)])
+ self.assertEqual(len(rset.rows), 2)
+ self.assertEqual(rset.description, [('Societe',), ('Societe',)])
def test_insert_2(self):
rset = self.execute("INSERT Personne X, Personne Y: X nom 'bidule', Y nom 'tutu'")
- self.assertEquals(rset.description, [('Personne', 'Personne')])
+ self.assertEqual(rset.description, [('Personne', 'Personne')])
rset = self.execute('Personne X WHERE X nom "bidule" or X nom "tutu"')
self.assert_(rset.rows)
- self.assertEquals(rset.description, [('Personne',), ('Personne',)])
+ self.assertEqual(rset.description, [('Personne',), ('Personne',)])
def test_insert_3(self):
self.execute("INSERT Personne X: X nom Y WHERE U login 'admin', U login Y")
rset = self.execute('Personne X WHERE X nom "admin"')
self.assert_(rset.rows)
- self.assertEquals(rset.description, [('Personne',)])
+ self.assertEqual(rset.description, [('Personne',)])
def test_insert_4(self):
self.execute("INSERT Societe Y: Y nom 'toto'")
self.execute("INSERT Personne X: X nom 'bidule', X travaille Y WHERE Y nom 'toto'")
rset = self.execute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
self.assert_(rset.rows)
- self.assertEquals(rset.description, [('Personne', 'Societe',)])
+ self.assertEqual(rset.description, [('Personne', 'Societe',)])
def test_insert_4bis(self):
peid = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
@@ -937,7 +944,7 @@
self.execute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X nom 'bidule'")
rset = self.execute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
self.assert_(rset.rows)
- self.assertEquals(rset.description, [('Personne', 'Societe',)])
+ self.assertEqual(rset.description, [('Personne', 'Societe',)])
def test_insert_5bis(self):
peid = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
@@ -945,45 +952,45 @@
{'x': peid})
rset = self.execute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
self.assert_(rset.rows)
- self.assertEquals(rset.description, [('Personne', 'Societe',)])
+ self.assertEqual(rset.description, [('Personne', 'Societe',)])
def test_insert_6(self):
self.execute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto', X travaille Y")
rset = self.execute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
self.assert_(rset.rows)
- self.assertEquals(rset.description, [('Personne', 'Societe',)])
+ self.assertEqual(rset.description, [('Personne', 'Societe',)])
def test_insert_7(self):
self.execute("INSERT Personne X, Societe Y: X nom N, Y nom 'toto', X travaille Y WHERE U login 'admin', U login N")
rset = self.execute('Any X, Y WHERE X nom "admin", Y nom "toto", X travaille Y')
self.assert_(rset.rows)
- self.assertEquals(rset.description, [('Personne', 'Societe',)])
+ self.assertEqual(rset.description, [('Personne', 'Societe',)])
def test_insert_7_2(self):
self.execute("INSERT Personne X, Societe Y: X nom N, Y nom 'toto', X travaille Y WHERE U login N")
rset = self.execute('Any X, Y WHERE Y nom "toto", X travaille Y')
- self.assertEquals(len(rset), 2)
- self.assertEquals(rset.description, [('Personne', 'Societe',),
+ self.assertEqual(len(rset), 2)
+ self.assertEqual(rset.description, [('Personne', 'Societe',),
('Personne', 'Societe',)])
def test_insert_8(self):
self.execute("INSERT Societe Y, Personne X: Y nom N, X nom 'toto', X travaille Y WHERE U login 'admin', U login N")
rset = self.execute('Any X, Y WHERE X nom "toto", Y nom "admin", X travaille Y')
self.assert_(rset.rows)
- self.assertEquals(rset.description, [('Personne', 'Societe',)])
+ self.assertEqual(rset.description, [('Personne', 'Societe',)])
def test_insert_9(self):
self.execute("INSERT Societe X: X nom 'Lo'")
self.execute("INSERT Societe X: X nom 'Gi'")
self.execute("INSERT SubDivision X: X nom 'Lab'")
rset = self.execute("INSERT Personne X: X nom N, X travaille Y, X travaille_subdivision Z WHERE Y is Societe, Z is SubDivision, Y nom N")
- self.assertEquals(len(rset), 2)
- self.assertEquals(rset.description, [('Personne',), ('Personne',)])
- # self.assertSetEquals(set(x.nom for x in rset.entities()),
+ self.assertEqual(len(rset), 2)
+ self.assertEqual(rset.description, [('Personne',), ('Personne',)])
+ # self.assertSetEqual(set(x.nom for x in rset.entities()),
# ['Lo', 'Gi'])
- # self.assertSetEquals(set(y.nom for x in rset.entities() for y in x.travaille),
+ # self.assertSetEqual(set(y.nom for x in rset.entities() for y in x.travaille),
# ['Lo', 'Gi'])
- # self.assertEquals([y.nom for x in rset.entities() for y in x.travaille_subdivision],
+ # self.assertEqual([y.nom for x in rset.entities() for y in x.travaille_subdivision],
# ['Lab', 'Lab'])
def test_insert_query_error(self):
@@ -1005,7 +1012,7 @@
rset = self.execute('INSERT CWUser E, EmailAddress EM: E login "X", E upassword "X", '
'E primary_email EM, EM address "X", E in_group G '
'WHERE G name "managers"')
- self.assertEquals(list(rset.description[0]), ['CWUser', 'EmailAddress'])
+ self.assertEqual(list(rset.description[0]), ['CWUser', 'EmailAddress'])
# deletion queries tests ##################################################
@@ -1020,10 +1027,10 @@
def test_delete_2(self):
rset = self.execute("INSERT Personne X, Personne Y, Societe Z : X nom 'syt', Y nom 'adim', Z nom 'Logilab', X travaille Z, Y travaille Z")
- self.assertEquals(len(rset), 1)
- self.assertEquals(len(rset[0]), 3)
- self.assertEquals(rset.description[0], ('Personne', 'Personne', 'Societe'))
- self.assertEquals(self.execute('Any N WHERE X nom N, X eid %s'% rset[0][0])[0][0], 'syt')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(len(rset[0]), 3)
+ self.assertEqual(rset.description[0], ('Personne', 'Personne', 'Societe'))
+ self.assertEqual(self.execute('Any N WHERE X nom N, X eid %s'% rset[0][0])[0][0], 'syt')
rset = self.execute('Personne X WHERE X travaille Y, Y nom "Logilab"')
self.assertEqual(len(rset.rows), 2, rset.rows)
self.execute("DELETE X travaille Y WHERE X is Personne, Y nom 'Logilabo'")
@@ -1049,16 +1056,16 @@
teid2 = self.execute("INSERT Folder T: T name 'tutu'")[0][0]
self.execute('SET X see_also Y WHERE X eid %s, Y eid %s' % (teid1, teid2))
rset = self.execute('Any X,Y WHERE X see_also Y')
- self.assertEquals(len(rset) , 2, rset.rows)
+ self.assertEqual(len(rset) , 2, rset.rows)
self.execute('DELETE X see_also Y WHERE X eid %s, Y eid %s' % (teid1, teid2))
rset = self.execute('Any X,Y WHERE X see_also Y')
- self.assertEquals(len(rset) , 0)
+ self.assertEqual(len(rset) , 0)
self.execute('SET X see_also Y WHERE X eid %s, Y eid %s' % (teid1, teid2))
rset = self.execute('Any X,Y WHERE X see_also Y')
- self.assertEquals(len(rset) , 2)
+ self.assertEqual(len(rset) , 2)
self.execute('DELETE X see_also Y WHERE X eid %s, Y eid %s' % (teid2, teid1))
rset = self.execute('Any X,Y WHERE X see_also Y')
- self.assertEquals(len(rset) , 0)
+ self.assertEqual(len(rset) , 0)
def test_nonregr_delete_cache(self):
"""test that relations are properly cleaned when an entity is deleted
@@ -1073,9 +1080,9 @@
self.o.execute(s, "DELETE Email X")
sqlc = s.pool['system']
sqlc.execute('SELECT * FROM recipients_relation')
- self.assertEquals(len(sqlc.fetchall()), 0)
+ self.assertEqual(len(sqlc.fetchall()), 0)
sqlc.execute('SELECT * FROM owned_by_relation WHERE eid_from=%s'%eeid)
- self.assertEquals(len(sqlc.fetchall()), 0)
+ self.assertEqual(len(sqlc.fetchall()), 0)
def test_nonregr_delete_cache2(self):
eid = self.execute("INSERT Folder T: T name 'toto'")[0][0]
@@ -1088,13 +1095,13 @@
self.execute("DELETE Folder T WHERE T eid %s" % eid)
self.commit()
rset = self.execute("Any X WHERE X eid %(x)s", {'x': eid})
- self.assertEquals(rset.rows, [])
+ self.assertEqual(rset.rows, [])
rset = self.execute("Any X WHERE X eid %s" % eid)
- self.assertEquals(rset.rows, [])
+ self.assertEqual(rset.rows, [])
rset = self.execute("Folder X WHERE X eid %(x)s", {'x': eid})
- self.assertEquals(rset.rows, [])
+ self.assertEqual(rset.rows, [])
rset = self.execute("Folder X WHERE X eid %s" %eid)
- self.assertEquals(rset.rows, [])
+ self.assertEqual(rset.rows, [])
# update queries tests ####################################################
@@ -1110,7 +1117,7 @@
def test_update_2(self):
peid, seid = self.execute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto'")[0]
rset = self.execute("SET X travaille Y WHERE X nom 'bidule', Y nom 'toto'")
- self.assertEquals(tuplify(rset.rows), [(peid, seid)])
+ self.assertEqual(tuplify(rset.rows), [(peid, seid)])
rset = self.execute('Any X, Y WHERE X travaille Y')
self.assertEqual(len(rset.rows), 1)
@@ -1138,8 +1145,8 @@
peid1 = self.execute("INSERT Personne Y: Y nom 'tutu'")[0][0]
peid2 = self.execute("INSERT Personne Y: Y nom 'toto'")[0][0]
self.execute("SET X nom 'tutu', Y nom 'toto' WHERE X nom 'toto', Y nom 'tutu'")
- self.assertEquals(self.execute('Any X WHERE X nom "toto"').rows, [[peid1]])
- self.assertEquals(self.execute('Any X WHERE X nom "tutu"').rows, [[peid2]])
+ self.assertEqual(self.execute('Any X WHERE X nom "toto"').rows, [[peid1]])
+ self.assertEqual(self.execute('Any X WHERE X nom "tutu"').rows, [[peid2]])
def test_update_multiple2(self):
ueid = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto'")[0][0]
@@ -1162,13 +1169,13 @@
{'order': orders[splitidx]})
orders2 = [r[0] for r in self.execute('Any O ORDERBY O WHERE ST name "Personne", X from_entity ST, X ordernum O')]
orders = orders[:splitidx] + [o+1 for o in orders[splitidx:]]
- self.assertEquals(orders2, orders)
+ self.assertEqual(orders2, orders)
def test_update_string_concat(self):
beid = self.execute("INSERT Bookmark Y: Y title 'toto', Y path '/view'")[0][0]
self.execute('SET X title XN + %(suffix)s WHERE X is Bookmark, X title XN', {'suffix': u'-moved'})
newname = self.execute('Any XN WHERE X eid %(x)s, X title XN', {'x': beid})[0][0]
- self.assertEquals(newname, 'toto-moved')
+ self.assertEqual(newname, 'toto-moved')
def test_update_query_error(self):
self.execute("INSERT Personne Y: Y nom 'toto'")
@@ -1176,39 +1183,38 @@
self.assertRaises(QueryError, self.execute, "SET X nom 'toto', X has_text 'tutu' WHERE X is Personne")
self.assertRaises(QueryError, self.execute, "SET X login 'tutu', X eid %s" % cnx.user(self.session).eid)
-
# upassword encryption tests #################################################
def test_insert_upassword(self):
rset = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto'")
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(rset.description, [('CWUser',)])
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(rset.description, [('CWUser',)])
self.assertRaises(Unauthorized,
self.execute, "Any P WHERE X is CWUser, X login 'bob', X upassword P")
cursor = self.pool['system']
cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'"
% (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX))
passwd = str(cursor.fetchone()[0])
- self.assertEquals(passwd, crypt_password('toto', passwd[:2]))
+ self.assertEqual(passwd, crypt_password('toto', passwd[:2]))
rset = self.execute("Any X WHERE X is CWUser, X login 'bob', X upassword %(pwd)s",
{'pwd': Binary(passwd)})
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(rset.description, [('CWUser',)])
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(rset.description, [('CWUser',)])
def test_update_upassword(self):
cursor = self.pool['system']
rset = self.execute("INSERT CWUser X: X login 'bob', X upassword %(pwd)s", {'pwd': 'toto'})
- self.assertEquals(rset.description[0][0], 'CWUser')
+ self.assertEqual(rset.description[0][0], 'CWUser')
rset = self.execute("SET X upassword %(pwd)s WHERE X is CWUser, X login 'bob'",
{'pwd': 'tutu'})
cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'"
% (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX))
passwd = str(cursor.fetchone()[0])
- self.assertEquals(passwd, crypt_password('tutu', passwd[:2]))
+ self.assertEqual(passwd, crypt_password('tutu', passwd[:2]))
rset = self.execute("Any X WHERE X is CWUser, X login 'bob', X upassword %(pwd)s",
{'pwd': Binary(passwd)})
- self.assertEquals(len(rset.rows), 1)
- self.assertEquals(rset.description, [('CWUser',)])
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(rset.description, [('CWUser',)])
# non regression tests ####################################################
@@ -1216,11 +1222,11 @@
teid = self.execute("INSERT Tag X: X name 'tag'")[0][0]
self.execute("SET X tags Y WHERE X name 'tag', Y is State, Y name 'activated'")
rset = self.execute('Any X WHERE T tags X')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
rset = self.execute('Any T WHERE T tags X, X is State')
- self.assertEquals(rset.rows, [[teid]])
+ self.assertEqual(rset.rows, [[teid]])
rset = self.execute('Any T WHERE T tags X')
- self.assertEquals(rset.rows, [[teid]])
+ self.assertEqual(rset.rows, [[teid]])
def test_nonregr_2(self):
teid = self.execute("INSERT Tag X: X name 'tag'")[0][0]
@@ -1229,7 +1235,7 @@
{'g': geid, 't': teid})
rset = self.execute('Any X WHERE E eid %(x)s, E tags X',
{'x': teid})
- self.assertEquals(rset.rows, [[geid]])
+ self.assertEqual(rset.rows, [[geid]])
def test_nonregr_3(self):
"""bad sql generated on the second query (destination_state is not
@@ -1237,7 +1243,7 @@
"""
rset = self.execute('Any S,ES,T WHERE S state_of WF, WF workflow_of ET, ET name "CWUser",'
'ES allowed_transition T, T destination_state S')
- self.assertEquals(len(rset.rows), 2)
+ self.assertEqual(len(rset.rows), 2)
def test_nonregr_4(self):
# fix variables'type, else we get (nb of entity types with a 'name' attribute)**3
@@ -1245,7 +1251,7 @@
# by the server (or client lib)
rset = self.execute('Any ER,SE,OE WHERE SE name "Comment", ER name "comments", OE name "Comment",'
'ER is CWRType, SE is CWEType, OE is CWEType')
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
def test_nonregr_5(self):
# jpl #15505: equivalent queries returning different result sets
@@ -1265,9 +1271,9 @@
rset4 = self.execute('Any N,U WHERE N todo_by U, T eid %s,'
'N filed_under T, W concerne N,'
'W filed_under A, A eid %s' % (teid1, teid2))
- self.assertEquals(rset1.rows, rset2.rows)
- self.assertEquals(rset1.rows, rset3.rows)
- self.assertEquals(rset1.rows, rset4.rows)
+ self.assertEqual(rset1.rows, rset2.rows)
+ self.assertEqual(rset1.rows, rset3.rows)
+ self.assertEqual(rset1.rows, rset4.rows)
def test_nonregr_6(self):
self.execute('Any N,COUNT(S) GROUPBY N ORDERBY COUNT(N) WHERE S name N, S is State')
@@ -1285,7 +1291,7 @@
rset = self.execute('Any lower(N) ORDERBY LOWER(N) WHERE X is Tag, X name N,'
'X owned_by U, U eid %(x)s',
{'x':self.session.user.eid})
- self.assertEquals(rset.rows, [[u'\xe9name0']])
+ self.assertEqual(rset.rows, [[u'\xe9name0']])
def test_nonregr_description(self):
@@ -1299,8 +1305,8 @@
self.execute("SET X in_basket B WHERE X is Personne")
self.execute("SET X in_basket B WHERE X is Societe")
rset = self.execute('Any X WHERE X in_basket B, B eid %s' % beid)
- self.assertEquals(len(rset), 2)
- self.assertEquals(rset.description, [('Personne',), ('Societe',)])
+ self.assertEqual(len(rset), 2)
+ self.assertEqual(rset.description, [('Personne',), ('Societe',)])
def test_nonregr_cache_1(self):
@@ -1310,19 +1316,19 @@
{'y': beid})
rset = self.execute("Any X WHERE X in_basket B, B eid %(x)s",
{'x': beid})
- self.assertEquals(rset.rows, [[peid]])
+ self.assertEqual(rset.rows, [[peid]])
rset = self.execute("Any X WHERE X in_basket B, B eid %(x)s",
{'x': beid})
- self.assertEquals(rset.rows, [[peid]])
+ self.assertEqual(rset.rows, [[peid]])
def test_nonregr_has_text_cache(self):
eid1 = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
eid2 = self.execute("INSERT Personne X: X nom 'tag'")[0][0]
self.commit()
rset = self.execute("Any X WHERE X has_text %(text)s", {'text': 'bidule'})
- self.assertEquals(rset.rows, [[eid1]])
+ self.assertEqual(rset.rows, [[eid1]])
rset = self.execute("Any X WHERE X has_text %(text)s", {'text': 'tag'})
- self.assertEquals(rset.rows, [[eid2]])
+ self.assertEqual(rset.rows, [[eid2]])
def test_nonregr_sortterm_management(self):
"""Error: Variable has no attribute 'sql' in rql2sql.py (visit_variable)
@@ -1347,16 +1353,16 @@
self.execute("SET X todo_by Y WHERE X is Note, Y eid %s" % ueid)
rset = self.execute('Any N WHERE N todo_by U, N is Note, U eid %s, N filed_under T, T eid %s'
% (ueid, teid1))
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
def test_nonregr_XXX(self):
teid = self.execute('Transition S WHERE S name "deactivate"')[0][0]
rset = self.execute('Any O WHERE O is State, '
'S eid %(x)s, S transition_of ET, O state_of ET', {'x': teid})
- self.assertEquals(len(rset), 2)
+ self.assertEqual(len(rset), 2)
rset = self.execute('Any O WHERE O is State, NOT S destination_state O, '
'S eid %(x)s, S transition_of ET, O state_of ET', {'x': teid})
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
def test_nonregr_set_datetime(self):
@@ -1373,9 +1379,9 @@
ueid = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto', X in_group G "
"WHERE G name 'users'")[0][0]
rset = self.execute("CWUser U")
- self.assertEquals(len(rset), 3) # bob + admin + anon
+ self.assertEqual(len(rset), 3) # bob + admin + anon
rset = self.execute("Any U WHERE NOT U owned_by U")
- self.assertEquals(len(rset), 0) # even admin created at repo initialization time should belong to itself
+ self.assertEqual(len(rset), 0) # even admin created at repo initialization time should belong to itself
def test_nonreg_update_index(self):
# this is the kind of queries generated by "cubicweb-ctl db-check -ry"
@@ -1390,11 +1396,11 @@
self.execute('Any X,S, MAX(T) GROUPBY X,S ORDERBY S WHERE X is CWUser, T tags X, S eid IN(%s), X in_state S' % seid)
def test_nonregr_solution_cache(self):
- self.skip('XXX should be fixed or documented') # (doesn't occur if cache key is provided.)
+ self.skipTest('XXX should be fixed or documented') # (doesn't occur if cache key is provided.)
rset = self.execute('Any X WHERE X is CWUser, X eid %(x)s', {'x':self.ueid})
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
rset = self.execute('Any X WHERE X is CWUser, X eid %(x)s', {'x':12345})
- self.assertEquals(len(rset), 0)
+ self.assertEqual(len(rset), 0)
def test_nonregr_final_norestr(self):
self.assertRaises(BadRQLQuery, self.execute, 'Date X')
--- a/server/test/unittest_repository.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_repository.py Wed Sep 29 16:16:32 2010 +0200
@@ -32,7 +32,7 @@
from yams.constraints import UniqueConstraint
from cubicweb import (BadConnectionId, RepositoryError, ValidationError,
- UnknownEid, AuthenticationError)
+ UnknownEid, AuthenticationError, Unauthorized)
from cubicweb.selectors import is_instance
from cubicweb.schema import CubicWebSchema, RQLConstraint
from cubicweb.dbapi import connect, multiple_connections_unfix
@@ -65,10 +65,10 @@
self.session.set_pool()
cu = self.session.system_sql('SELECT %s FROM %s WHERE %s is NULL' % (
namecol, table, finalcol))
- self.assertEquals(cu.fetchall(), [])
+ self.assertEqual(cu.fetchall(), [])
cu = self.session.system_sql('SELECT %s FROM %s WHERE %s=%%(final)s ORDER BY %s'
% (namecol, table, finalcol, namecol), {'final': 'TRUE'})
- self.assertEquals(cu.fetchall(), [(u'Boolean',), (u'Bytes',),
+ self.assertEqual(cu.fetchall(), [(u'Boolean',), (u'Bytes',),
(u'Date',), (u'Datetime',),
(u'Decimal',),(u'Float',),
(u'Int',),
@@ -84,15 +84,15 @@
";")
cu = self.session.system_sql(sql)
rows = cu.fetchall()
- self.assertEquals(len(rows), 3)
+ self.assertEqual(len(rows), 3)
self.test_unique_together()
finally:
self.repo.set_schema(origshema)
def test_unique_together(self):
person = self.repo.schema.eschema('Personne')
- self.assertEquals(len(person._unique_together), 1)
- self.assertUnorderedIterableEquals(person._unique_together[0],
+ self.assertEqual(len(person._unique_together), 1)
+ self.assertItemsEqual(person._unique_together[0],
('nom', 'prenom', 'inline2'))
def test_schema_has_owner(self):
@@ -136,15 +136,39 @@
repo.close(cnxid)
self.assert_(repo.connect(u"barnabé", password=u"héhéhé".encode('UTF8')))
- def test_invalid_entity_rollback(self):
+ def test_rollback_on_commit_error(self):
cnxid = self.repo.connect(self.admlogin, password=self.admpassword)
- # no group
self.repo.execute(cnxid,
'INSERT CWUser X: X login %(login)s, X upassword %(passwd)s',
{'login': u"tutetute", 'passwd': 'tutetute'})
self.assertRaises(ValidationError, self.repo.commit, cnxid)
self.failIf(self.repo.execute(cnxid, 'CWUser X WHERE X login "tutetute"'))
+ def test_rollback_on_execute_validation_error(self):
+ class ValidationErrorAfterHook(Hook):
+ __regid__ = 'valerror-after-hook'
+ __select__ = Hook.__select__ & is_instance('CWGroup')
+ events = ('after_update_entity',)
+ def __call__(self):
+ raise ValidationError(self.entity.eid, {})
+ with self.temporary_appobjects(ValidationErrorAfterHook):
+ self.assertRaises(ValidationError,
+ self.execute, 'SET X name "toto" WHERE X is CWGroup, X name "guests"')
+ self.failIf(self.execute('Any X WHERE X is CWGroup, X name "toto"'))
+
+ def test_rollback_on_execute_unauthorized(self):
+ class UnauthorizedAfterHook(Hook):
+ __regid__ = 'unauthorized-after-hook'
+ __select__ = Hook.__select__ & is_instance('CWGroup')
+ events = ('after_update_entity',)
+ def __call__(self):
+ raise Unauthorized()
+ with self.temporary_appobjects(UnauthorizedAfterHook):
+ self.assertRaises(Unauthorized,
+ self.execute, 'SET X name "toto" WHERE X is CWGroup, X name "guests"')
+ self.failIf(self.execute('Any X WHERE X is CWGroup, X name "toto"'))
+
+
def test_close(self):
repo = self.repo
cnxid = repo.connect(self.admlogin, password=self.admpassword)
@@ -161,14 +185,14 @@
cnxid = repo.connect(self.admlogin, password=self.admpassword)
repo.set_shared_data(cnxid, 'data', 4)
cnxid2 = repo.connect(self.admlogin, password=self.admpassword)
- self.assertEquals(repo.get_shared_data(cnxid, 'data'), 4)
- self.assertEquals(repo.get_shared_data(cnxid2, 'data'), None)
+ self.assertEqual(repo.get_shared_data(cnxid, 'data'), 4)
+ self.assertEqual(repo.get_shared_data(cnxid2, 'data'), None)
repo.set_shared_data(cnxid2, 'data', 5)
- self.assertEquals(repo.get_shared_data(cnxid, 'data'), 4)
- self.assertEquals(repo.get_shared_data(cnxid2, 'data'), 5)
+ self.assertEqual(repo.get_shared_data(cnxid, 'data'), 4)
+ self.assertEqual(repo.get_shared_data(cnxid2, 'data'), 5)
repo.get_shared_data(cnxid2, 'data', pop=True)
- self.assertEquals(repo.get_shared_data(cnxid, 'data'), 4)
- self.assertEquals(repo.get_shared_data(cnxid2, 'data'), None)
+ self.assertEqual(repo.get_shared_data(cnxid, 'data'), 4)
+ self.assertEqual(repo.get_shared_data(cnxid2, 'data'), None)
repo.close(cnxid)
repo.close(cnxid2)
self.assertRaises(BadConnectionId, repo.get_shared_data, cnxid, 'data')
@@ -188,19 +212,19 @@
cnxid = repo.connect(self.admlogin, password=self.admpassword)
# check db state
result = repo.execute(cnxid, 'Personne X')
- self.assertEquals(result.rowcount, 0)
+ self.assertEqual(result.rowcount, 0)
# rollback entity insertion
repo.execute(cnxid, "INSERT Personne X: X nom 'bidule'")
result = repo.execute(cnxid, 'Personne X')
- self.assertEquals(result.rowcount, 1)
+ self.assertEqual(result.rowcount, 1)
repo.rollback(cnxid)
result = repo.execute(cnxid, 'Personne X')
- self.assertEquals(result.rowcount, 0, result.rows)
+ self.assertEqual(result.rowcount, 0, result.rows)
# commit
repo.execute(cnxid, "INSERT Personne X: X nom 'bidule'")
repo.commit(cnxid)
result = repo.execute(cnxid, 'Personne X')
- self.assertEquals(result.rowcount, 1)
+ self.assertEqual(result.rowcount, 1)
def test_transaction_base2(self):
repo = self.repo
@@ -208,10 +232,10 @@
# rollback relation insertion
repo.execute(cnxid, "SET U in_group G WHERE U login 'admin', G name 'guests'")
result = repo.execute(cnxid, "Any U WHERE U in_group G, U login 'admin', G name 'guests'")
- self.assertEquals(result.rowcount, 1)
+ self.assertEqual(result.rowcount, 1)
repo.rollback(cnxid)
result = repo.execute(cnxid, "Any U WHERE U in_group G, U login 'admin', G name 'guests'")
- self.assertEquals(result.rowcount, 0, result.rows)
+ self.assertEqual(result.rowcount, 0, result.rows)
def test_transaction_base3(self):
repo = self.repo
@@ -222,13 +246,13 @@
user = session.user
user.cw_adapt_to('IWorkflowable').fire_transition('deactivate')
rset = repo.execute(cnxid, 'TrInfo T WHERE T wf_info_for X, X eid %(x)s', {'x': user.eid})
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
repo.rollback(cnxid)
rset = repo.execute(cnxid, 'TrInfo T WHERE T wf_info_for X, X eid %(x)s', {'x': user.eid})
- self.assertEquals(len(rset), 0)
+ self.assertEqual(len(rset), 0)
def test_transaction_interleaved(self):
- self.skip('implement me')
+ self.skipTest('implement me')
def test_close_kill_processing_request(self):
repo = self.repo
@@ -246,14 +270,14 @@
repo.commit(cnxid)
try:
ex = self.assertRaises(Exception, run_transaction)
- self.assertEquals(str(ex), 'try to access pool on a closed session')
+ self.assertEqual(str(ex), 'try to access pool on a closed session')
finally:
t.join()
def test_initial_schema(self):
schema = self.repo.schema
# check order of attributes is respected
- self.assertListEquals([r.type for r in schema.eschema('CWAttribute').ordered_relations()
+ self.assertListEqual([r.type for r in schema.eschema('CWAttribute').ordered_relations()
if not r.type in ('eid', 'is', 'is_instance_of', 'identity',
'creation_date', 'modification_date', 'cwuri',
'owned_by', 'created_by',
@@ -266,11 +290,11 @@
'indexed', 'fulltextindexed', 'internationalizable',
'defaultval', 'description', 'description_format'])
- self.assertEquals(schema.eschema('CWEType').main_attribute(), 'name')
- self.assertEquals(schema.eschema('State').main_attribute(), 'name')
+ self.assertEqual(schema.eschema('CWEType').main_attribute(), 'name')
+ self.assertEqual(schema.eschema('State').main_attribute(), 'name')
constraints = schema.rschema('name').rdef('CWEType', 'String').constraints
- self.assertEquals(len(constraints), 2)
+ self.assertEqual(len(constraints), 2)
for cstr in constraints[:]:
if isinstance(cstr, UniqueConstraint):
constraints.remove(cstr)
@@ -278,17 +302,17 @@
else:
self.fail('unique constraint not found')
sizeconstraint = constraints[0]
- self.assertEquals(sizeconstraint.min, None)
- self.assertEquals(sizeconstraint.max, 64)
+ self.assertEqual(sizeconstraint.min, None)
+ self.assertEqual(sizeconstraint.max, 64)
constraints = schema.rschema('relation_type').rdef('CWAttribute', 'CWRType').constraints
- self.assertEquals(len(constraints), 1)
+ self.assertEqual(len(constraints), 1)
cstr = constraints[0]
self.assert_(isinstance(cstr, RQLConstraint))
- self.assertEquals(cstr.restriction, 'O final TRUE')
+ self.assertEqual(cstr.restriction, 'O final TRUE')
ownedby = schema.rschema('owned_by')
- self.assertEquals(ownedby.objects('CWEType'), ('CWUser',))
+ self.assertEqual(ownedby.objects('CWEType'), ('CWUser',))
def test_pyro(self):
import Pyro
@@ -319,7 +343,7 @@
schema = cnx.get_schema()
self.failUnless(cnx.vreg)
self.failUnless('etypes'in cnx.vreg)
- self.assertEquals(schema.__hashmode__, None)
+ self.assertEqual(schema.__hashmode__, None)
cu = cnx.cursor()
rset = cu.execute('Any U,G WHERE U in_group G')
user = iter(rset.entities()).next()
@@ -337,25 +361,25 @@
repo = self.repo
cnxid = repo.connect(self.admlogin, password=self.admpassword)
session = repo._get_session(cnxid, setpool=True)
- self.assertEquals(repo.type_and_source_from_eid(1, session),
+ self.assertEqual(repo.type_and_source_from_eid(1, session),
('CWGroup', 'system', None))
- self.assertEquals(repo.type_from_eid(1, session), 'CWGroup')
- self.assertEquals(repo.source_from_eid(1, session).uri, 'system')
- self.assertEquals(repo.eid2extid(repo.system_source, 1, session), None)
+ self.assertEqual(repo.type_from_eid(1, session), 'CWGroup')
+ self.assertEqual(repo.source_from_eid(1, session).uri, 'system')
+ self.assertEqual(repo.eid2extid(repo.system_source, 1, session), None)
class dummysource: uri = 'toto'
self.assertRaises(UnknownEid, repo.eid2extid, dummysource, 1, session)
def test_public_api(self):
- self.assertEquals(self.repo.get_schema(), self.repo.schema)
- self.assertEquals(self.repo.source_defs(), {'system': {'adapter': 'native', 'uri': 'system'}})
+ self.assertEqual(self.repo.get_schema(), self.repo.schema)
+ self.assertEqual(self.repo.source_defs(), {'system': {'adapter': 'native', 'uri': 'system'}})
# .properties() return a result set
- self.assertEquals(self.repo.properties().rql, 'Any K,V WHERE P is CWProperty,P pkey K, P value V, NOT P for_user U')
+ self.assertEqual(self.repo.properties().rql, 'Any K,V WHERE P is CWProperty,P pkey K, P value V, NOT P for_user U')
def test_session_api(self):
repo = self.repo
cnxid = repo.connect(self.admlogin, password=self.admpassword)
- self.assertEquals(repo.user_info(cnxid), (5, 'admin', set([u'managers']), {}))
- self.assertEquals(repo.describe(cnxid, 1), (u'CWGroup', u'system', None))
+ self.assertEqual(repo.user_info(cnxid), (5, 'admin', set([u'managers']), {}))
+ self.assertEqual(repo.describe(cnxid, 1), (u'CWGroup', u'system', None))
repo.close(cnxid)
self.assertRaises(BadConnectionId, repo.user_info, cnxid)
self.assertRaises(BadConnectionId, repo.describe, cnxid, 1)
@@ -363,12 +387,12 @@
def test_shared_data_api(self):
repo = self.repo
cnxid = repo.connect(self.admlogin, password=self.admpassword)
- self.assertEquals(repo.get_shared_data(cnxid, 'data'), None)
+ self.assertEqual(repo.get_shared_data(cnxid, 'data'), None)
repo.set_shared_data(cnxid, 'data', 4)
- self.assertEquals(repo.get_shared_data(cnxid, 'data'), 4)
+ self.assertEqual(repo.get_shared_data(cnxid, 'data'), 4)
repo.get_shared_data(cnxid, 'data', pop=True)
repo.get_shared_data(cnxid, 'whatever', pop=True)
- self.assertEquals(repo.get_shared_data(cnxid, 'data'), None)
+ self.assertEqual(repo.get_shared_data(cnxid, 'data'), None)
repo.close(cnxid)
self.assertRaises(BadConnectionId, repo.set_shared_data, cnxid, 'data', 0)
self.assertRaises(BadConnectionId, repo.get_shared_data, cnxid, 'data')
@@ -394,14 +418,14 @@
{'x': note.eid, 'p': p1.eid})
rset = self.execute('Any P WHERE A todo_by P, A eid %(x)s',
{'x': note.eid})
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
p2 = self.request().create_entity('Personne', nom=u'tutu')
self.execute('SET A todo_by P WHERE A eid %(x)s, P eid %(p)s',
{'x': note.eid, 'p': p2.eid})
rset = self.execute('Any P WHERE A todo_by P, A eid %(x)s',
{'x': note.eid})
- self.assertEquals(len(rset), 1)
- self.assertEquals(rset.rows[0][0], p2.eid)
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.rows[0][0], p2.eid)
def test_delete_if_object_inlined_singlecard(self):
req = self.request()
@@ -409,7 +433,7 @@
req.create_entity('Personne', nom=u'Vincent', fiche=c)
req.create_entity('Personne', nom=u'Florent', fiche=c)
self.commit()
- self.assertEquals(len(c.reverse_fiche), 1)
+ self.assertEqual(len(c.reverse_fiche), 1)
def test_set_attributes_in_before_update(self):
# local hook
@@ -430,7 +454,7 @@
addr.set_attributes(address=u'a@b.com')
rset = self.execute('Any A,AA WHERE X eid %(x)s, X address A, X alias AA',
{'x': addr.eid})
- self.assertEquals(rset.rows, [[u'a@b.com', u'foo']])
+ self.assertEqual(rset.rows, [[u'a@b.com', u'foo']])
def test_set_attributes_in_before_add(self):
# local hook
@@ -477,7 +501,7 @@
def test_source_from_eid(self):
self.session.set_pool()
- self.assertEquals(self.repo.source_from_eid(1, self.session),
+ self.assertEqual(self.repo.source_from_eid(1, self.session),
self.repo.sources_by_uri['system'])
def test_source_from_eid_raise(self):
@@ -486,7 +510,7 @@
def test_type_from_eid(self):
self.session.set_pool()
- self.assertEquals(self.repo.type_from_eid(1, self.session), 'CWGroup')
+ self.assertEqual(self.repo.type_from_eid(1, self.session), 'CWGroup')
def test_type_from_eid_raise(self):
self.session.set_pool()
@@ -503,12 +527,12 @@
self.assertIsInstance(data[0][3], datetime)
data[0] = list(data[0])
data[0][3] = None
- self.assertEquals(tuplify(data), [(-1, 'Personne', 'system', None, None)])
+ self.assertEqual(tuplify(data), [(-1, 'Personne', 'system', None, None)])
self.repo.delete_info(self.session, entity, 'system', None)
#self.repo.commit()
cu = self.session.system_sql('SELECT * FROM entities WHERE eid = -1')
data = cu.fetchall()
- self.assertEquals(data, [])
+ self.assertEqual(data, [])
class FTITC(CubicWebTC):
@@ -518,7 +542,7 @@
eidp = self.execute('INSERT Personne X: X nom "toto", X prenom "tutu"')[0][0]
self.commit()
ts = datetime.now()
- self.assertEquals(len(self.execute('Personne X WHERE X has_text "tutu"')), 1)
+ self.assertEqual(len(self.execute('Personne X WHERE X has_text "tutu"')), 1)
self.session.set_pool()
cu = self.session.system_sql('SELECT mtime, eid FROM entities WHERE eid = %s' % eidp)
omtime = cu.fetchone()[0]
@@ -527,23 +551,23 @@
time.sleep(1 - (ts.second - int(ts.second)))
self.execute('SET X nom "tata" WHERE X eid %(x)s', {'x': eidp})
self.commit()
- self.assertEquals(len(self.execute('Personne X WHERE X has_text "tutu"')), 1)
+ self.assertEqual(len(self.execute('Personne X WHERE X has_text "tutu"')), 1)
self.session.set_pool()
cu = self.session.system_sql('SELECT mtime FROM entities WHERE eid = %s' % eidp)
mtime = cu.fetchone()[0]
self.failUnless(omtime < mtime)
self.commit()
date, modified, deleted = self.repo.entities_modified_since(('Personne',), omtime)
- self.assertEquals(modified, [('Personne', eidp)])
- self.assertEquals(deleted, [])
+ self.assertEqual(modified, [('Personne', eidp)])
+ self.assertEqual(deleted, [])
date, modified, deleted = self.repo.entities_modified_since(('Personne',), mtime)
- self.assertEquals(modified, [])
- self.assertEquals(deleted, [])
+ self.assertEqual(modified, [])
+ self.assertEqual(deleted, [])
self.execute('DELETE Personne X WHERE X eid %(x)s', {'x': eidp})
self.commit()
date, modified, deleted = self.repo.entities_modified_since(('Personne',), omtime)
- self.assertEquals(modified, [])
- self.assertEquals(deleted, [('Personne', eidp)])
+ self.assertEqual(modified, [])
+ self.assertEqual(deleted, [('Personne', eidp)])
def test_fulltext_container_entity(self):
assert self.schema.rschema('use_email').fulltext_container == 'subject'
@@ -551,27 +575,27 @@
toto = req.create_entity('EmailAddress', address=u'toto@logilab.fr')
self.commit()
rset = req.execute('Any X WHERE X has_text %(t)s', {'t': 'toto'})
- self.assertEquals(rset.rows, [])
+ self.assertEqual(rset.rows, [])
req.user.set_relations(use_email=toto)
self.commit()
rset = req.execute('Any X WHERE X has_text %(t)s', {'t': 'toto'})
- self.assertEquals(rset.rows, [[req.user.eid]])
+ self.assertEqual(rset.rows, [[req.user.eid]])
req.execute('DELETE X use_email Y WHERE X login "admin", Y eid %(y)s',
{'y': toto.eid})
self.commit()
rset = req.execute('Any X WHERE X has_text %(t)s', {'t': 'toto'})
- self.assertEquals(rset.rows, [])
+ self.assertEqual(rset.rows, [])
tutu = req.create_entity('EmailAddress', address=u'tutu@logilab.fr')
req.user.set_relations(use_email=tutu)
self.commit()
rset = req.execute('Any X WHERE X has_text %(t)s', {'t': 'tutu'})
- self.assertEquals(rset.rows, [[req.user.eid]])
+ self.assertEqual(rset.rows, [[req.user.eid]])
tutu.set_attributes(address=u'hip@logilab.fr')
self.commit()
rset = req.execute('Any X WHERE X has_text %(t)s', {'t': 'tutu'})
- self.assertEquals(rset.rows, [])
+ self.assertEqual(rset.rows, [])
rset = req.execute('Any X WHERE X has_text %(t)s', {'t': 'hip'})
- self.assertEquals(rset.rows, [[req.user.eid]])
+ self.assertEqual(rset.rows, [[req.user.eid]])
def test_no_uncessary_ftiindex_op(self):
req = self.request()
@@ -584,7 +608,7 @@
def test_versions_inserted(self):
inserted = [r[0] for r in self.execute('Any K ORDERBY K WHERE P pkey K, P pkey ~= "system.version.%"')]
- self.assertEquals(inserted,
+ self.assertEqual(inserted,
[u'system.version.basket', u'system.version.card', u'system.version.comment',
u'system.version.cubicweb', u'system.version.email',
u'system.version.file', u'system.version.folder',
@@ -616,15 +640,15 @@
eidp = self.execute('INSERT Personne X: X nom "toto"')[0][0]
eidn = self.execute('INSERT Note X: X type "T"')[0][0]
self.execute('SET N ecrit_par Y WHERE N type "T", Y nom "toto"')
- self.assertEquals(CALLED, [('before_add_relation', eidn, 'ecrit_par', eidp),
+ self.assertEqual(CALLED, [('before_add_relation', eidn, 'ecrit_par', eidp),
('after_add_relation', eidn, 'ecrit_par', eidp)])
CALLED[:] = ()
self.execute('DELETE N ecrit_par Y WHERE N type "T", Y nom "toto"')
- self.assertEquals(CALLED, [('before_delete_relation', eidn, 'ecrit_par', eidp),
+ self.assertEqual(CALLED, [('before_delete_relation', eidn, 'ecrit_par', eidp),
('after_delete_relation', eidn, 'ecrit_par', eidp)])
CALLED[:] = ()
eidn = self.execute('INSERT Note N: N ecrit_par P WHERE P nom "toto"')[0][0]
- self.assertEquals(CALLED, [('before_add_relation', eidn, 'ecrit_par', eidp),
+ self.assertEqual(CALLED, [('before_add_relation', eidn, 'ecrit_par', eidp),
('after_add_relation', eidn, 'ecrit_par', eidp)])
def test_unique_contraint(self):
@@ -638,7 +662,7 @@
req = self.request()
req.create_entity('Note', type=u'todo', inline1=a01)
ex = self.assertRaises(ValidationError, req.cnx.commit)
- self.assertEquals(ex.errors, {'inline1-subject': u'RQLUniqueConstraint S type T, S inline1 A1, A1 todo_by C, Y type T, Y inline1 A2, A2 todo_by C failed'})
+ self.assertEqual(ex.errors, {'inline1-subject': u'RQLUniqueConstraint S type T, S inline1 A1, A1 todo_by C, Y type T, Y inline1 A2, A2 todo_by C failed'})
if __name__ == '__main__':
unittest_main()
--- a/server/test/unittest_rql2sql.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_rql2sql.py Wed Sep 29 16:16:32 2010 +0200
@@ -1096,12 +1096,15 @@
for sol in delete.solutions:
s.add(sol.get(var))
return s
- self.assertEquals(var_sols('FROM_ENTITYOBJECT'), set(('CWAttribute', 'CWRelation')))
- self.assertEquals(var_sols('FROM_ENTITYOBJECT'), delete.defined_vars['FROM_ENTITYOBJECT'].stinfo['possibletypes'])
- self.assertEquals(var_sols('ISOBJECT'),
+ self.assertEqual(var_sols('FROM_ENTITYOBJECT'), set(('CWAttribute', 'CWRelation')))
+ self.assertEqual(var_sols('FROM_ENTITYOBJECT'), delete.defined_vars['FROM_ENTITYOBJECT'].stinfo['possibletypes'])
+ self.assertEqual(var_sols('ISOBJECT'),
set(x.type for x in self.schema.entities() if not x.final))
- self.assertEquals(var_sols('ISOBJECT'), delete.defined_vars['ISOBJECT'].stinfo['possibletypes'])
+ self.assertEqual(var_sols('ISOBJECT'), delete.defined_vars['ISOBJECT'].stinfo['possibletypes'])
+
+def strip(text):
+ return '\n'.join(l.strip() for l in text.strip().splitlines())
class PostgresSQLGeneratorTC(RQLGeneratorTC):
schema = schema
@@ -1118,7 +1121,7 @@
r, nargs, cbs = self.o.generate(union, args,
varmap=varmap)
args.update(nargs)
- self.assertLinesEquals((r % args).strip(), self._norm_sql(sql), striplines=True)
+ self.assertMultiLineEqual(strip(r % args), self._norm_sql(sql))
except Exception, ex:
if 'r' in locals():
try:
@@ -1200,7 +1203,7 @@
def test_is_null_transform(self):
union = self._prepare('Any X WHERE X login %(login)s')
r, args, cbs = self.o.generate(union, {'login': None})
- self.assertLinesEquals((r % args).strip(),
+ self.assertMultiLineEqual((r % args).strip(),
'''SELECT _X.cw_eid
FROM cw_CWUser AS _X
WHERE _X.cw_login IS NULL''')
@@ -1454,8 +1457,8 @@
try:
union = self._prepare('Any R WHERE X ref R')
r, nargs, cbs = self.o.generate(union, args={})
- self.assertLinesEquals(r.strip(), 'SELECT _X.cw_ref\nFROM cw_Affaire AS _X')
- self.assertEquals(cbs, {0: [cb]})
+ self.assertMultiLineEqual(r.strip(), 'SELECT _X.cw_ref\nFROM cw_Affaire AS _X')
+ self.assertEqual(cbs, {0: [cb]})
finally:
self.o.attr_map.clear()
@@ -1712,7 +1715,7 @@
rqlst = mock_object(defined_vars={})
rqlst.defined_vars['A'] = mock_object(scope=rqlst, stinfo={}, _q_invariant=True)
rqlst.defined_vars['B'] = mock_object(scope=rqlst, stinfo={}, _q_invariant=False)
- self.assertEquals(remove_unused_solutions(rqlst, [{'A': 'RugbyGroup', 'B': 'RugbyTeam'},
+ self.assertEqual(remove_unused_solutions(rqlst, [{'A': 'RugbyGroup', 'B': 'RugbyTeam'},
{'A': 'FootGroup', 'B': 'FootTeam'}], {}, None),
([{'A': 'RugbyGroup', 'B': 'RugbyTeam'},
{'A': 'FootGroup', 'B': 'FootTeam'}],
@@ -1723,7 +1726,7 @@
rqlst = mock_object(defined_vars={})
rqlst.defined_vars['A'] = mock_object(scope=rqlst, stinfo={}, _q_invariant=True)
rqlst.defined_vars['B'] = mock_object(scope=rqlst, stinfo={}, _q_invariant=False)
- self.assertEquals(remove_unused_solutions(rqlst, [{'A': 'RugbyGroup', 'B': 'RugbyTeam'},
+ self.assertEqual(remove_unused_solutions(rqlst, [{'A': 'RugbyGroup', 'B': 'RugbyTeam'},
{'A': 'FootGroup', 'B': 'RugbyTeam'}], {}, None),
([{'A': 'RugbyGroup', 'B': 'RugbyTeam'}], {}, set())
)
--- a/server/test/unittest_rqlannotation.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_rqlannotation.py Wed Sep 29 16:16:32 2010 +0200
@@ -41,256 +41,256 @@
def test_0_1(self):
rqlst = self._prepare('Any SEN,RN,OEN WHERE X from_entity SE, SE eid 44, X relation_type R, R eid 139, X to_entity OE, OE eid 42, R name RN, SE name SEN, OE name OEN')
- self.assertEquals(rqlst.defined_vars['SE']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['OE']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['R']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['SE'].stinfo['attrvar'], None)
- self.assertEquals(rqlst.defined_vars['OE'].stinfo['attrvar'], None)
- self.assertEquals(rqlst.defined_vars['R'].stinfo['attrvar'], None)
+ self.assertEqual(rqlst.defined_vars['SE']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['OE']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['R']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['SE'].stinfo['attrvar'], None)
+ self.assertEqual(rqlst.defined_vars['OE'].stinfo['attrvar'], None)
+ self.assertEqual(rqlst.defined_vars['R'].stinfo['attrvar'], None)
def test_0_2(self):
rqlst = self._prepare('Any O WHERE NOT S ecrit_par O, S eid 1, S inline1 P, O inline2 P')
- self.assertEquals(rqlst.defined_vars['P']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['O'].stinfo['attrvar'], None)
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['O'].stinfo['attrvar'], None)
def test_0_4(self):
rqlst = self._prepare('Any A,B,C WHERE A eid 12,A comment B, A ?wf_info_for C')
- self.assertEquals(rqlst.defined_vars['A']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['A']._q_invariant, False)
self.assert_(rqlst.defined_vars['B'].stinfo['attrvar'])
- self.assertEquals(rqlst.defined_vars['C']._q_invariant, False)
- self.assertEquals(rqlst.solutions, [{'A': 'TrInfo', 'B': 'String', 'C': 'Affaire'},
+ self.assertEqual(rqlst.defined_vars['C']._q_invariant, False)
+ self.assertEqual(rqlst.solutions, [{'A': 'TrInfo', 'B': 'String', 'C': 'Affaire'},
{'A': 'TrInfo', 'B': 'String', 'C': 'CWUser'},
{'A': 'TrInfo', 'B': 'String', 'C': 'Note'}])
def test_0_5(self):
rqlst = self._prepare('Any P WHERE N ecrit_par P, N eid 0')
- self.assertEquals(rqlst.defined_vars['N']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['P']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['N']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, True)
def test_0_6(self):
rqlst = self._prepare('Any P WHERE NOT N ecrit_par P, N eid 512')
- self.assertEquals(rqlst.defined_vars['P']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
def test_0_7(self):
rqlst = self._prepare('Personne X,Y where X nom NX, Y nom NX, X eid XE, not Y eid XE')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
self.assert_(rqlst.defined_vars['XE'].stinfo['attrvar'])
def test_0_8(self):
rqlst = self._prepare('Any P WHERE X eid 0, NOT X connait P')
- self.assertEquals(rqlst.defined_vars['P']._q_invariant, False)
- #self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
- self.assertEquals(len(rqlst.solutions), 1, rqlst.solutions)
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
+ #self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(len(rqlst.solutions), 1, rqlst.solutions)
def test_0_10(self):
rqlst = self._prepare('Any X WHERE X concerne Y, Y is Note')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_0_11(self):
rqlst = self._prepare('Any X WHERE X todo_by Y, X is Affaire')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_0_12(self):
rqlst = self._prepare('Personne P WHERE P concerne A, A concerne S, S nom "Logilab"')
- self.assertEquals(rqlst.defined_vars['P']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['A']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['S']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['A']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, False)
def test_1_0(self):
rqlst = self._prepare('Any X,Y WHERE X created_by Y, X eid 5, NOT Y eid 6')
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_1_1(self):
rqlst = self._prepare('Any X,Y WHERE X created_by Y, X eid 5, NOT Y eid IN (6,7)')
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_2(self):
rqlst = self._prepare('Any X WHERE X identity Y, Y eid 1')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
def test_7(self):
rqlst = self._prepare('Personne X,Y where X nom NX, Y nom NX, X eid XE, not Y eid XE')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_8(self):
# DISTINCT Any P WHERE P require_group %(g)s, NOT %(u)s has_group_permission P, P is CWPermission
rqlst = self._prepare('DISTINCT Any X WHERE A concerne X, NOT N migrated_from X, '
'X is Note, N eid 1')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
def test_diff_scope_identity_deamb(self):
rqlst = self._prepare('Any X WHERE X concerne Y, Y is Note, EXISTS(Y identity Z, Z migrated_from N)')
- self.assertEquals(rqlst.defined_vars['Z']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['Z']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_optional_inlined(self):
rqlst = self._prepare('Any X,S where X from_state S?')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['S']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, True)
def test_optional_inlined_2(self):
rqlst = self._prepare('Any N,A WHERE N? inline1 A')
- self.assertEquals(rqlst.defined_vars['N']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['A']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['N']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['A']._q_invariant, False)
def test_optional_1(self):
rqlst = self._prepare('Any X,S WHERE X travaille S?')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['S']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, True)
def test_greater_eid(self):
rqlst = self._prepare('Any X WHERE X eid > 5')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_greater_eid_typed(self):
rqlst = self._prepare('Any X WHERE X eid > 5, X is Note')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_max_eid(self):
rqlst = self._prepare('Any MAX(X)')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_max_eid_typed(self):
rqlst = self._prepare('Any MAX(X) WHERE X is Note')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
def test_all_entities(self):
rqlst = self._prepare('Any X')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_all_typed_entity(self):
rqlst = self._prepare('Any X WHERE X is Note')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
def test_has_text_1(self):
rqlst = self._prepare('Any X WHERE X has_text "toto tata"')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['X'].stinfo['principal'].r_type, 'has_text')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X'].stinfo['principal'].r_type, 'has_text')
def test_has_text_2(self):
rqlst = self._prepare('Any X WHERE X is Personne, X has_text "coucou"')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['X'].stinfo['principal'].r_type, 'has_text')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X'].stinfo['principal'].r_type, 'has_text')
def test_not_relation_1(self):
# P can't be invariant since deambiguification caused by "NOT X require_permission P"
# is not considered by generated sql (NOT EXISTS(...))
rqlst = self._prepare('Any P,G WHERE P require_group G, NOT X require_permission P')
- self.assertEquals(rqlst.defined_vars['P']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['G']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['G']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_not_relation_2(self):
rqlst = self._prepare('TrInfo X WHERE X eid 2, NOT X from_state Y, Y is State')
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
def test_not_relation_3(self):
rqlst = self._prepare('Any X, Y WHERE X eid 1, Y eid in (2, 3)')
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_not_relation_4_1(self):
rqlst = self._prepare('Note X WHERE NOT Y evaluee X')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_not_relation_4_2(self):
rqlst = self._prepare('Any X WHERE NOT Y evaluee X')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_not_relation_4_3(self):
rqlst = self._prepare('Any Y WHERE NOT Y evaluee X')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_not_relation_4_4(self):
rqlst = self._prepare('Any X WHERE NOT Y evaluee X, Y is CWUser')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_not_relation_4_5(self):
rqlst = self._prepare('Any X WHERE NOT Y evaluee X, Y eid %s, X is Note' % self.ueid)
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.solutions, [{'X': 'Note'}])
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.solutions, [{'X': 'Note'}])
def test_not_relation_5_1(self):
rqlst = self._prepare('Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_not_relation_5_2(self):
rqlst = self._prepare('DISTINCT Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_not_relation_6(self):
rqlst = self._prepare('Personne P where NOT P concerne A')
- self.assertEquals(rqlst.defined_vars['P']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['A']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['A']._q_invariant, True)
def test_not_relation_7(self):
rqlst = self._prepare('Any K,V WHERE P is CWProperty, P pkey K, P value V, NOT P for_user U')
- self.assertEquals(rqlst.defined_vars['P']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['U']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, True)
def test_exists_1(self):
rqlst = self._prepare('Any U WHERE U eid IN (1,2), EXISTS(X owned_by U)')
- self.assertEquals(rqlst.defined_vars['U']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_exists_2(self):
rqlst = self._prepare('Any U WHERE EXISTS(U eid IN (1,2), X owned_by U)')
- self.assertEquals(rqlst.defined_vars['U']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_exists_3(self):
rqlst = self._prepare('Any U WHERE EXISTS(X owned_by U, X bookmarked_by U)')
- self.assertEquals(rqlst.defined_vars['U']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_exists_4(self):
rqlst = self._prepare('Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), EXISTS(X read_permission Y)')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_exists_5(self):
rqlst = self._prepare('DISTINCT Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), EXISTS(X read_permission Y)')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_not_exists_1(self):
rqlst = self._prepare('Any U WHERE NOT EXISTS(X owned_by U, X bookmarked_by U)')
- self.assertEquals(rqlst.defined_vars['U']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_not_exists_2(self):
rqlst = self._prepare('Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT EXISTS(X read_permission Y)')
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_not_exists_distinct_1(self):
rqlst = self._prepare('DISTINCT Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT EXISTS(X read_permission Y)')
- self.assertEquals(rqlst.defined_vars['Y']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_or_1(self):
rqlst = self._prepare('Any X WHERE X concerne B OR C concerne X, B eid 12, C eid 13')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
def test_or_2(self):
rqlst = self._prepare('Any X WHERE X created_by U, X concerne B OR C concerne X, B eid 12, C eid 13')
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['U']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['X'].stinfo['principal'].r_type, 'created_by')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X'].stinfo['principal'].r_type, 'created_by')
def test_or_3(self):
rqlst = self._prepare('Any N WHERE A evaluee N or EXISTS(N todo_by U)')
- self.assertEquals(rqlst.defined_vars['N']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['A']._q_invariant, True)
- self.assertEquals(rqlst.defined_vars['U']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['N']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['A']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, True)
def test_or_exists_1(self):
# query generated by security rewriting
@@ -300,30 +300,30 @@
'OR (EXISTS(I concerne H?, H owned_by D, H is Societe, A identity I, I is Affaire))) '
'OR (EXISTS(J concerne G?, G owned_by D, G is SubDivision, A identity J, J is Affaire))) '
'OR (EXISTS(K concerne F?, F owned_by D, F is Division, A identity K, K is Affaire)))')
- self.assertEquals(rqlst.defined_vars['A']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['S']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['A']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, False)
def test_or_exists_2(self):
rqlst = self._prepare('Any U WHERE EXISTS(U in_group G, G name "managers") OR EXISTS(X owned_by U, X bookmarked_by U)')
- self.assertEquals(rqlst.defined_vars['U']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['G']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['G']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_or_exists_3(self):
rqlst = self._prepare('Any COUNT(S),CS GROUPBY CS ORDERBY 1 DESC LIMIT 10 '
'WHERE C is Societe, S concerne C, C nom CS, '
'(EXISTS(S owned_by D)) OR (EXISTS(S documented_by N, N title "published"))')
- self.assertEquals(rqlst.defined_vars['S']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, True)
rqlst = self._prepare('Any COUNT(S),CS GROUPBY CS ORDERBY 1 DESC LIMIT 10 '
'WHERE S is Affaire, C is Societe, S concerne C, C nom CS, '
'(EXISTS(S owned_by D)) OR (EXISTS(S documented_by N, N title "published"))')
- self.assertEquals(rqlst.defined_vars['S']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, True)
def test_nonregr_ambiguity(self):
rqlst = self._prepare('Note N WHERE N attachment F')
# N may be an image as well, not invariant
- self.assertEquals(rqlst.defined_vars['N']._q_invariant, False)
- self.assertEquals(rqlst.defined_vars['F']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['N']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['F']._q_invariant, True)
if __name__ == '__main__':
from logilab.common.testlib import unittest_main
--- a/server/test/unittest_schemaserial.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_schemaserial.py Wed Sep 29 16:16:32 2010 +0200
@@ -47,7 +47,7 @@
class Schema2RQLTC(TestCase):
def test_eschema2rql1(self):
- self.assertListEquals(list(eschema2rql(schema.eschema('CWAttribute'))),
+ self.assertListEqual(list(eschema2rql(schema.eschema('CWAttribute'))),
[
('INSERT CWEType X: X description %(description)s,X final %(final)s,X name %(name)s',
{'description': u'define a final relation: link a final relation type from a non final entity to a final entity type. used to build the instance schema',
@@ -55,13 +55,13 @@
])
def test_eschema2rql2(self):
- self.assertListEquals(list(eschema2rql(schema.eschema('String'))), [
+ self.assertListEqual(list(eschema2rql(schema.eschema('String'))), [
('INSERT CWEType X: X description %(description)s,X final %(final)s,X name %(name)s',
{'description': u'', 'final': True, 'name': u'String'})])
def test_eschema2rql_specialization(self):
# x: None since eschema.eid are None
- self.assertListEquals(sorted(specialize2rql(schema)),
+ self.assertListEqual(sorted(specialize2rql(schema)),
[('SET X specializes ET WHERE X eid %(x)s, ET eid %(et)s',
{'et': None, 'x': None}),
('SET X specializes ET WHERE X eid %(x)s, ET eid %(et)s',
@@ -72,7 +72,7 @@
{'et': None, 'x': None})])
def test_rschema2rql1(self):
- self.assertListEquals(list(rschema2rql(schema.rschema('relation_type'), cstrtypemap)),
+ self.assertListEqual(list(rschema2rql(schema.rschema('relation_type'), cstrtypemap)),
[
('INSERT CWRType X: X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X name %(name)s,X symmetric %(symmetric)s',
{'description': u'link a relation definition to its relation type', 'symmetric': False, 'name': u'relation_type', 'final' : False, 'fulltext_container': None, 'inlined': True}),
@@ -93,7 +93,7 @@
])
def test_rschema2rql2(self):
- self.assertListEquals(list(rschema2rql(schema.rschema('add_permission'), cstrtypemap)),
+ self.assertListEqual(list(rschema2rql(schema.rschema('add_permission'), cstrtypemap)),
[
('INSERT CWRType X: X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X name %(name)s,X symmetric %(symmetric)s', {'description': u'', 'symmetric': False, 'name': u'add_permission', 'final': False, 'fulltext_container': None, 'inlined': False}),
@@ -113,7 +113,7 @@
])
def test_rschema2rql3(self):
- self.assertListEquals(list(rschema2rql(schema.rschema('cardinality'), cstrtypemap)),
+ self.assertListEqual(list(rschema2rql(schema.rschema('cardinality'), cstrtypemap)),
[
('INSERT CWRType X: X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X name %(name)s,X symmetric %(symmetric)s',
{'description': u'', 'symmetric': False, 'name': u'cardinality', 'final': True, 'fulltext_container': None, 'inlined': False}),
@@ -136,7 +136,7 @@
])
def test_rdef2rql(self):
- self.assertListEquals(list(rdef2rql(schema['description_format'].rdefs[('CWRType', 'String')], cstrtypemap)),
+ self.assertListEqual(list(rdef2rql(schema['description_format'].rdefs[('CWRType', 'String')], cstrtypemap)),
[
('INSERT CWAttribute X: X cardinality %(cardinality)s,X defaultval %(defaultval)s,X description %(description)s,X fulltextindexed %(fulltextindexed)s,X indexed %(indexed)s,X internationalizable %(internationalizable)s,X ordernum %(ordernum)s,X relation_type ER,X from_entity SE,X to_entity OE WHERE SE eid %(se)s,ER eid %(rt)s,OE eid %(oe)s',
{'se': None, 'rt': None, 'oe': None,
@@ -148,19 +148,19 @@
def test_updateeschema2rql1(self):
- self.assertListEquals(list(updateeschema2rql(schema.eschema('CWAttribute'), 1)),
+ self.assertListEqual(list(updateeschema2rql(schema.eschema('CWAttribute'), 1)),
[('SET X description %(description)s,X final %(final)s,X name %(name)s WHERE X eid %(x)s',
{'description': u'define a final relation: link a final relation type from a non final entity to a final entity type. used to build the instance schema', 'x': 1, 'final': False, 'name': u'CWAttribute'}),
])
def test_updateeschema2rql2(self):
- self.assertListEquals(list(updateeschema2rql(schema.eschema('String'), 1)),
+ self.assertListEqual(list(updateeschema2rql(schema.eschema('String'), 1)),
[('SET X description %(description)s,X final %(final)s,X name %(name)s WHERE X eid %(x)s',
{'description': u'', 'x': 1, 'final': True, 'name': u'String'})
])
def test_updaterschema2rql1(self):
- self.assertListEquals(list(updaterschema2rql(schema.rschema('relation_type'), 1)),
+ self.assertListEqual(list(updaterschema2rql(schema.rschema('relation_type'), 1)),
[
('SET X description %(description)s,X final %(final)s,X fulltext_container %(fulltext_container)s,X inlined %(inlined)s,X name %(name)s,X symmetric %(symmetric)s WHERE X eid %(x)s',
{'x': 1, 'symmetric': False,
@@ -176,7 +176,7 @@
'inlined': False, 'name': u'add_permission'})
]
for i, (rql, args) in enumerate(updaterschema2rql(schema.rschema('add_permission'), 1)):
- yield self.assertEquals, (rql, args), expected[i]
+ yield self.assertEqual, (rql, args), expected[i]
class Perms2RQLTC(TestCase):
GROUP_MAPPING = {
@@ -187,7 +187,7 @@
}
def test_eperms2rql1(self):
- self.assertListEquals([(rql, kwargs) for rql, kwargs in erperms2rql(schema.eschema('CWEType'), self.GROUP_MAPPING)],
+ self.assertListEqual([(rql, kwargs) for rql, kwargs in erperms2rql(schema.eschema('CWEType'), self.GROUP_MAPPING)],
[('SET X read_permission Y WHERE Y eid %(g)s, X eid %(x)s', {'g': 0}),
('SET X read_permission Y WHERE Y eid %(g)s, X eid %(x)s', {'g': 1}),
('SET X read_permission Y WHERE Y eid %(g)s, X eid %(x)s', {'g': 2}),
@@ -197,7 +197,7 @@
])
def test_rperms2rql2(self):
- self.assertListEquals([(rql, kwargs) for rql, kwargs in erperms2rql(schema.rschema('read_permission').rdef('CWEType', 'CWGroup'), self.GROUP_MAPPING)],
+ self.assertListEqual([(rql, kwargs) for rql, kwargs in erperms2rql(schema.rschema('read_permission').rdef('CWEType', 'CWGroup'), self.GROUP_MAPPING)],
[('SET X read_permission Y WHERE Y eid %(g)s, X eid %(x)s', {'g': 0}),
('SET X read_permission Y WHERE Y eid %(g)s, X eid %(x)s', {'g': 1}),
('SET X read_permission Y WHERE Y eid %(g)s, X eid %(x)s', {'g': 2}),
@@ -206,7 +206,7 @@
])
def test_rperms2rql3(self):
- self.assertListEquals([(rql, kwargs) for rql, kwargs in erperms2rql(schema.rschema('name').rdef('CWEType', 'String'), self.GROUP_MAPPING)],
+ self.assertListEqual([(rql, kwargs) for rql, kwargs in erperms2rql(schema.rschema('name').rdef('CWEType', 'String'), self.GROUP_MAPPING)],
[('SET X read_permission Y WHERE Y eid %(g)s, X eid %(x)s', {'g': 0}),
('SET X read_permission Y WHERE Y eid %(g)s, X eid %(x)s', {'g': 1}),
('SET X read_permission Y WHERE Y eid %(g)s, X eid %(x)s', {'g': 2}),
@@ -214,7 +214,7 @@
])
#def test_perms2rql(self):
- # self.assertListEquals(perms2rql(schema, self.GROUP_MAPPING),
+ # self.assertListEqual(perms2rql(schema, self.GROUP_MAPPING),
# ['INSERT CWEType X: X name 'Societe', X final FALSE'])
--- a/server/test/unittest_security.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_security.py Wed Sep 29 16:16:32 2010 +0200
@@ -81,10 +81,10 @@
cnx = self.login('iaminusersgrouponly')
self.hijack_source_execute()
self.execute('Any U WHERE NOT A todo_by U, A is Affaire')
- self.assertEquals(self.query[0][1].as_string(),
+ self.assertEqual(self.query[0][1].as_string(),
'Any U WHERE NOT EXISTS(A todo_by U), A is Affaire')
self.execute('Any U WHERE NOT EXISTS(A todo_by U), A is Affaire')
- self.assertEquals(self.query[0][1].as_string(),
+ self.assertEqual(self.query[0][1].as_string(),
'Any U WHERE NOT EXISTS(A todo_by U), A is Affaire')
class SecurityTC(BaseSecurityTC):
@@ -103,7 +103,7 @@
cu = cnx.cursor()
cu.execute("INSERT Personne X: X nom 'bidule'")
self.assertRaises(Unauthorized, cnx.commit)
- self.assertEquals(cu.execute('Personne X').rowcount, 1)
+ self.assertEqual(cu.execute('Personne X').rowcount, 1)
def test_insert_rql_permission(self):
# test user can only add une affaire related to a societe he owns
@@ -113,7 +113,7 @@
self.assertRaises(Unauthorized, cnx.commit)
# test nothing has actually been inserted
self.restore_connection()
- self.assertEquals(self.execute('Affaire X').rowcount, 1)
+ self.assertEqual(self.execute('Affaire X').rowcount, 1)
cnx = self.login('iaminusersgrouponly')
cu = cnx.cursor()
cu.execute("INSERT Affaire X: X sujet 'cool'")
@@ -128,7 +128,7 @@
cu.execute( "SET X nom 'bidulechouette' WHERE X is Personne")
self.assertRaises(Unauthorized, cnx.commit)
self.restore_connection()
- self.assertEquals(self.execute('Personne X WHERE X nom "bidulechouette"').rowcount, 0)
+ self.assertEqual(self.execute('Personne X WHERE X nom "bidulechouette"').rowcount, 0)
def test_update_security_2(self):
cnx = self.login('anon')
@@ -139,7 +139,7 @@
#self.assertRaises(Unauthorized, cnx.commit)
# test nothing has actually been inserted
self.restore_connection()
- self.assertEquals(self.execute('Personne X WHERE X nom "bidulechouette"').rowcount, 0)
+ self.assertEqual(self.execute('Personne X WHERE X nom "bidulechouette"').rowcount, 0)
def test_update_security_3(self):
cnx = self.login('iaminusersgrouponly')
@@ -210,14 +210,14 @@
cnx.commit()
# to actually get Unauthorized exception, try to insert a relation were we can read both entities
rset = cu.execute('Personne P')
- self.assertEquals(len(rset), 1)
+ self.assertEqual(len(rset), 1)
ent = rset.get_entity(0, 0)
session.set_pool() # necessary
self.assertRaises(Unauthorized, ent.cw_check_perm, 'update')
self.assertRaises(Unauthorized,
cu.execute, "SET P travaille S WHERE P is Personne, S is Societe")
# test nothing has actually been inserted:
- self.assertEquals(cu.execute('Any P,S WHERE P travaille S,P is Personne, S is Societe').rowcount, 0)
+ self.assertEqual(cu.execute('Any P,S WHERE P travaille S,P is Personne, S is Societe').rowcount, 0)
cu.execute("INSERT Societe X: X nom 'chouette'")
cu.execute("SET A concerne S WHERE A is Affaire, S nom 'chouette'")
cnx.commit()
@@ -278,7 +278,7 @@
cnx = self.login('iaminusersgrouponly')
cu = cnx.cursor()
rset = cu.execute('Affaire X')
- self.assertEquals(rset.rows, [])
+ self.assertEqual(rset.rows, [])
self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x': eid})
# cache test
self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x': eid})
@@ -287,12 +287,12 @@
cu.execute("SET A concerne S WHERE A is Affaire, S is Societe")
cnx.commit()
rset = cu.execute('Any X WHERE X eid %(x)s', {'x': aff2})
- self.assertEquals(rset.rows, [[aff2]])
+ self.assertEqual(rset.rows, [[aff2]])
# more cache test w/ NOT eid
rset = cu.execute('Affaire X WHERE NOT X eid %(x)s', {'x': eid})
- self.assertEquals(rset.rows, [[aff2]])
+ self.assertEqual(rset.rows, [[aff2]])
rset = cu.execute('Affaire X WHERE NOT X eid %(x)s', {'x': aff2})
- self.assertEquals(rset.rows, [])
+ self.assertEqual(rset.rows, [])
# test can't update an attribute of an entity that can't be readen
self.assertRaises(Unauthorized, cu.execute, 'SET X sujet "hacked" WHERE X eid %(x)s', {'x': eid})
@@ -309,7 +309,7 @@
self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':aff2}))
# XXX would be nice if it worked
rset = cu.execute("Affaire X WHERE X sujet 'cool'")
- self.assertEquals(len(rset), 0)
+ self.assertEqual(len(rset), 0)
finally:
affschema.set_action_permissions('read', origperms)
cnx.close()
@@ -329,7 +329,7 @@
self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':aff2}))
self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':card1}))
rset = cu.execute("Any X WHERE X has_text 'cool'")
- self.assertEquals(sorted(eid for eid, in rset.rows),
+ self.assertEqual(sorted(eid for eid, in rset.rows),
[card1, aff2])
def test_read_erqlexpr_has_text2(self):
@@ -340,9 +340,9 @@
cnx = self.login('iaminusersgrouponly')
cu = cnx.cursor()
rset = cu.execute('Any N WHERE N has_text "bidule"')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
rset = cu.execute('Any N WITH N BEING (Any N WHERE N has_text "bidule")')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
def test_read_erqlexpr_optional_rel(self):
self.execute("INSERT Personne X: X nom 'bidule'")
@@ -352,7 +352,7 @@
cnx = self.login('anon')
cu = cnx.cursor()
rset = cu.execute('Any N,U WHERE N has_text "bidule", N owned_by U?')
- self.assertEquals(len(rset.rows), 1, rset.rows)
+ self.assertEqual(len(rset.rows), 1, rset.rows)
def test_read_erqlexpr_aggregat(self):
self.execute("INSERT Affaire X: X sujet 'cool'")[0][0]
@@ -360,22 +360,22 @@
cnx = self.login('iaminusersgrouponly')
cu = cnx.cursor()
rset = cu.execute('Any COUNT(X) WHERE X is Affaire')
- self.assertEquals(rset.rows, [[0]])
+ self.assertEqual(rset.rows, [[0]])
aff2 = cu.execute("INSERT Affaire X: X sujet 'cool'")[0][0]
soc1 = cu.execute("INSERT Societe X: X nom 'chouette'")[0][0]
cu.execute("SET A concerne S WHERE A is Affaire, S is Societe")
cnx.commit()
rset = cu.execute('Any COUNT(X) WHERE X is Affaire')
- self.assertEquals(rset.rows, [[1]])
+ self.assertEqual(rset.rows, [[1]])
rset = cu.execute('Any ETN, COUNT(X) GROUPBY ETN WHERE X is ET, ET name ETN')
values = dict(rset)
- self.assertEquals(values['Affaire'], 1)
- self.assertEquals(values['Societe'], 2)
+ self.assertEqual(values['Affaire'], 1)
+ self.assertEqual(values['Societe'], 2)
rset = cu.execute('Any ETN, COUNT(X) GROUPBY ETN WHERE X is ET, ET name ETN WITH X BEING ((Affaire X) UNION (Societe X))')
- self.assertEquals(len(rset), 2)
+ self.assertEqual(len(rset), 2)
values = dict(rset)
- self.assertEquals(values['Affaire'], 1)
- self.assertEquals(values['Societe'], 2)
+ self.assertEqual(values['Affaire'], 1)
+ self.assertEqual(values['Societe'], 2)
def test_attribute_security(self):
@@ -415,7 +415,7 @@
cnx.commit()
note2.cw_adapt_to('IWorkflowable').fire_transition('markasdone')
cnx.commit()
- self.assertEquals(len(cu.execute('Any X WHERE X in_state S, S name "todo", X eid %(x)s', {'x': note2.eid})),
+ self.assertEqual(len(cu.execute('Any X WHERE X in_state S, S name "todo", X eid %(x)s', {'x': note2.eid})),
0)
cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': note2.eid})
self.assertRaises(Unauthorized, cnx.commit)
@@ -433,11 +433,11 @@
rset = cu.execute('CWUser X')
self.failUnless(rset)
x = rset.get_entity(0, 0)
- self.assertEquals(x.login, None)
+ self.assertEqual(x.login, None)
self.failUnless(x.creation_date)
x = rset.get_entity(1, 0)
x.complete()
- self.assertEquals(x.login, None)
+ self.assertEqual(x.login, None)
self.failUnless(x.creation_date)
cnx.rollback()
@@ -456,9 +456,9 @@
affaire = self.execute('Any X WHERE X ref "ARCT01"').get_entity(0, 0)
affaire.cw_adapt_to('IWorkflowable').fire_transition('abort')
self.commit()
- self.assertEquals(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01"')),
+ self.assertEqual(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01"')),
1)
- self.assertEquals(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01",'
+ self.assertEqual(len(self.execute('TrInfo X WHERE X wf_info_for A, A ref "ARCT01",'
'X owned_by U, U login "admin"')),
1) # TrInfo at the above state change
cnx = self.login('iaminusersgrouponly')
@@ -473,9 +473,9 @@
cu = cnx.cursor()
# anonymous user can only read itself
rset = cu.execute('Any L WHERE X owned_by U, U login L')
- self.assertEquals(rset.rows, [['anon']])
+ self.assertEqual(rset.rows, [['anon']])
rset = cu.execute('CWUser X')
- self.assertEquals(rset.rows, [[anon.eid]])
+ self.assertEqual(rset.rows, [[anon.eid]])
# anonymous user can read groups (necessary to check allowed transitions for instance)
self.assert_(cu.execute('CWGroup X'))
# should only be able to read the anonymous user, not another one
@@ -488,7 +488,7 @@
# {'x': self.user.eid})
rset = cu.execute('CWUser X WHERE X eid %(x)s', {'x': anon.eid})
- self.assertEquals(rset.rows, [[anon.eid]])
+ self.assertEqual(rset.rows, [[anon.eid]])
# but can't modify it
cu.execute('SET X login "toto" WHERE X eid %(x)s', {'x': anon.eid})
self.assertRaises(Unauthorized, cnx.commit)
@@ -516,14 +516,14 @@
cnx = self.login('anon')
cu = cnx.cursor()
anoneid = self.session.user.eid
- self.assertEquals(cu.execute('Any T,P ORDERBY lower(T) WHERE B is Bookmark,B title T,B path P,'
+ self.assertEqual(cu.execute('Any T,P ORDERBY lower(T) WHERE B is Bookmark,B title T,B path P,'
'B bookmarked_by U, U eid %s' % anoneid).rows,
[['index', '?vid=index']])
- self.assertEquals(cu.execute('Any T,P ORDERBY lower(T) WHERE B is Bookmark,B title T,B path P,'
+ self.assertEqual(cu.execute('Any T,P ORDERBY lower(T) WHERE B is Bookmark,B title T,B path P,'
'B bookmarked_by U, U eid %(x)s', {'x': anoneid}).rows,
[['index', '?vid=index']])
# can read others bookmarks as well
- self.assertEquals(cu.execute('Any B where B is Bookmark, NOT B bookmarked_by U').rows,
+ self.assertEqual(cu.execute('Any B where B is Bookmark, NOT B bookmarked_by U').rows,
[[beid1]])
self.assertRaises(Unauthorized, cu.execute,'DELETE B bookmarked_by U')
self.assertRaises(Unauthorized,
@@ -535,7 +535,7 @@
cnx = self.login('anon')
cu = cnx.cursor()
names = [t for t, in cu.execute('Any N ORDERBY lower(N) WHERE X name N')]
- self.assertEquals(names, sorted(names, key=lambda x: x.lower()))
+ self.assertEqual(names, sorted(names, key=lambda x: x.lower()))
def test_in_state_without_update_perm(self):
"""check a user change in_state without having update permission on the
@@ -582,7 +582,7 @@
self.commit()
aff.cw_clear_relation_cache('wf_info_for', 'object')
trinfo = iworkflowable.latest_trinfo()
- self.assertEquals(trinfo.comment, 'bouh!')
+ self.assertEqual(trinfo.comment, 'bouh!')
# but not from_state/to_state
aff.cw_clear_relation_cache('wf_info_for', role='object')
self.assertRaises(Unauthorized,
--- a/server/test/unittest_session.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_session.py Wed Sep 29 16:16:32 2010 +0200
@@ -43,7 +43,7 @@
class MakeDescriptionTC(TestCase):
def test_known_values(self):
solution = {'A': 'Int', 'B': 'CWUser'}
- self.assertEquals(_make_description((Function('max', 'A'), Variable('B')), {}, solution),
+ self.assertEqual(_make_description((Function('max', 'A'), Variable('B')), {}, solution),
['Int','CWUser'])
class InternalSessionTC(CubicWebTC):
--- a/server/test/unittest_sqlutils.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_sqlutils.py Wed Sep 29 16:16:32 2010 +0200
@@ -36,13 +36,13 @@
def test_init(self):
o = SQLAdapterMixIn(BASE_CONFIG)
- self.assertEquals(o.dbhelper.dbencoding, 'UTF-8')
+ self.assertEqual(o.dbhelper.dbencoding, 'UTF-8')
def test_init_encoding(self):
config = BASE_CONFIG.copy()
config['db-encoding'] = 'ISO-8859-1'
o = SQLAdapterMixIn(config)
- self.assertEquals(o.dbhelper.dbencoding, 'ISO-8859-1')
+ self.assertEqual(o.dbhelper.dbencoding, 'ISO-8859-1')
if __name__ == '__main__':
unittest_main()
--- a/server/test/unittest_storage.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_storage.py Wed Sep 29 16:16:32 2010 +0200
@@ -78,15 +78,15 @@
expected_filepath = osp.join(self.tempdir, '%s_data_%s' %
(f1.eid, f1.data_name))
self.failUnless(osp.isfile(expected_filepath))
- self.assertEquals(file(expected_filepath).read(), 'the-data')
+ self.assertEqual(file(expected_filepath).read(), 'the-data')
self.rollback()
self.failIf(osp.isfile(expected_filepath))
f1 = self.create_file()
self.commit()
- self.assertEquals(file(expected_filepath).read(), 'the-data')
+ self.assertEqual(file(expected_filepath).read(), 'the-data')
f1.set_attributes(data=Binary('the new data'))
self.rollback()
- self.assertEquals(file(expected_filepath).read(), 'the-data')
+ self.assertEqual(file(expected_filepath).read(), 'the-data')
f1.cw_delete()
self.failUnless(osp.isfile(expected_filepath))
self.rollback()
@@ -98,14 +98,14 @@
def test_bfss_sqlite_fspath(self):
f1 = self.create_file()
expected_filepath = osp.join(self.tempdir, '%s_data_%s' % (f1.eid, f1.data_name))
- self.assertEquals(self.fspath(f1), expected_filepath)
+ self.assertEqual(self.fspath(f1), expected_filepath)
def test_bfss_fs_importing_doesnt_touch_path(self):
self.session.transaction_data['fs_importing'] = True
filepath = osp.abspath(__file__)
f1 = self.session.create_entity('File', data=Binary(filepath),
data_format=u'text/plain', data_name=u'foo')
- self.assertEquals(self.fspath(f1), filepath)
+ self.assertEqual(self.fspath(f1), filepath)
def test_source_storage_transparency(self):
with self.temporary_appobjects(DummyBeforeHook, DummyAfterHook):
@@ -114,11 +114,11 @@
def test_source_mapped_attribute_error_cases(self):
ex = self.assertRaises(QueryError, self.execute,
'Any X WHERE X data ~= "hop", X is File')
- self.assertEquals(str(ex), 'can\'t use File.data (X data ILIKE "hop") in restriction')
+ self.assertEqual(str(ex), 'can\'t use File.data (X data ILIKE "hop") in restriction')
ex = self.assertRaises(QueryError, self.execute,
'Any X, Y WHERE X data D, Y data D, '
'NOT X identity Y, X is File, Y is File')
- self.assertEquals(str(ex), "can't use D as a restriction variable")
+ self.assertEqual(str(ex), "can't use D as a restriction variable")
# query returning mix of mapped / regular attributes (only file.data
# mapped, not image.data for instance)
ex = self.assertRaises(QueryError, self.execute,
@@ -127,19 +127,19 @@
' UNION '
' (Any D WHERE X data D, X is File)'
')')
- self.assertEquals(str(ex), 'query fetch some source mapped attribute, some not')
+ self.assertEqual(str(ex), 'query fetch some source mapped attribute, some not')
ex = self.assertRaises(QueryError, self.execute,
'(Any D WHERE X data D, X is File)'
' UNION '
'(Any D WHERE X title D, X is Bookmark)')
- self.assertEquals(str(ex), 'query fetch some source mapped attribute, some not')
+ self.assertEqual(str(ex), 'query fetch some source mapped attribute, some not')
storages.set_attribute_storage(self.repo, 'State', 'name',
storages.BytesFileSystemStorage(self.tempdir))
try:
ex = self.assertRaises(QueryError,
self.execute, 'Any D WHERE X name D, X is IN (State, Transition)')
- self.assertEquals(str(ex), 'query fetch some source mapped attribute, some not')
+ self.assertEqual(str(ex), 'query fetch some source mapped attribute, some not')
finally:
storages.unset_attribute_storage(self.repo, 'State', 'name')
@@ -150,30 +150,30 @@
' UNION '
' (Any D, X WHERE X eid %(x)s, X data D)'
')', {'x': f1.eid})
- self.assertEquals(len(rset), 2)
- self.assertEquals(rset[0][0], f1.eid)
- self.assertEquals(rset[1][0], f1.eid)
- self.assertEquals(rset[0][1].getvalue(), 'the-data')
- self.assertEquals(rset[1][1].getvalue(), 'the-data')
+ self.assertEqual(len(rset), 2)
+ self.assertEqual(rset[0][0], f1.eid)
+ self.assertEqual(rset[1][0], f1.eid)
+ self.assertEqual(rset[0][1].getvalue(), 'the-data')
+ self.assertEqual(rset[1][1].getvalue(), 'the-data')
rset = self.execute('Any X,LENGTH(D) WHERE X eid %(x)s, X data D',
{'x': f1.eid})
- self.assertEquals(len(rset), 1)
- self.assertEquals(rset[0][0], f1.eid)
- self.assertEquals(rset[0][1], len('the-data'))
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset[0][0], f1.eid)
+ self.assertEqual(rset[0][1], len('the-data'))
rset = self.execute('Any X,LENGTH(D) WITH D,X BEING ('
' (Any D, X WHERE X eid %(x)s, X data D)'
' UNION '
' (Any D, X WHERE X eid %(x)s, X data D)'
')', {'x': f1.eid})
- self.assertEquals(len(rset), 2)
- self.assertEquals(rset[0][0], f1.eid)
- self.assertEquals(rset[1][0], f1.eid)
- self.assertEquals(rset[0][1], len('the-data'))
- self.assertEquals(rset[1][1], len('the-data'))
+ self.assertEqual(len(rset), 2)
+ self.assertEqual(rset[0][0], f1.eid)
+ self.assertEqual(rset[1][0], f1.eid)
+ self.assertEqual(rset[0][1], len('the-data'))
+ self.assertEqual(rset[1][1], len('the-data'))
ex = self.assertRaises(QueryError, self.execute,
'Any X,UPPER(D) WHERE X eid %(x)s, X data D',
{'x': f1.eid})
- self.assertEquals(str(ex), 'UPPER can not be called on mapped attribute')
+ self.assertEqual(str(ex), 'UPPER can not be called on mapped attribute')
def test_bfss_fs_importing_transparency(self):
@@ -181,7 +181,7 @@
filepath = osp.abspath(__file__)
f1 = self.session.create_entity('File', data=Binary(filepath),
data_format=u'text/plain', data_name=u'foo')
- self.assertEquals(f1.data.getvalue(), file(filepath).read(),
+ self.assertEqual(f1.data.getvalue(), file(filepath).read(),
'files content differ')
@tag('Storage', 'BFSS', 'update')
@@ -193,10 +193,10 @@
# update f1's local dict. We want the pure rql version to work
self.execute('SET F data %(d)s WHERE F eid %(f)s',
{'d': Binary('some other data'), 'f': f1.eid})
- self.assertEquals(f1.data.getvalue(), 'some other data')
+ self.assertEqual(f1.data.getvalue(), 'some other data')
self.commit()
f2 = self.execute('Any F WHERE F eid %(f)s, F is File', {'f': f1.eid}).get_entity(0, 0)
- self.assertEquals(f2.data.getvalue(), 'some other data')
+ self.assertEqual(f2.data.getvalue(), 'some other data')
@tag('Storage', 'BFSS', 'update', 'extension', 'commit')
def test_bfss_update_with_different_extension_commited(self):
@@ -208,7 +208,7 @@
self.commit()
old_path = self.fspath(f1)
self.failUnless(osp.isfile(old_path))
- self.assertEquals(osp.splitext(old_path)[1], '.txt')
+ self.assertEqual(osp.splitext(old_path)[1], '.txt')
self.execute('SET F data %(d)s, F data_name %(dn)s, F data_format %(df)s WHERE F eid %(f)s',
{'d': Binary('some other data'), 'f': f1.eid, 'dn': u'bar.jpg', 'df': u'image/jpeg'})
self.commit()
@@ -218,7 +218,7 @@
new_path = self.fspath(f2)
self.failIf(osp.isfile(old_path))
self.failUnless(osp.isfile(new_path))
- self.assertEquals(osp.splitext(new_path)[1], '.jpg')
+ self.assertEqual(osp.splitext(new_path)[1], '.jpg')
@tag('Storage', 'BFSS', 'update', 'extension', 'rollback')
def test_bfss_update_with_different_extension_rollbacked(self):
@@ -231,7 +231,7 @@
old_path = self.fspath(f1)
old_data = f1.data.getvalue()
self.failUnless(osp.isfile(old_path))
- self.assertEquals(osp.splitext(old_path)[1], '.txt')
+ self.assertEqual(osp.splitext(old_path)[1], '.txt')
self.execute('SET F data %(d)s, F data_name %(dn)s, F data_format %(df)s WHERE F eid %(f)s',
{'d': Binary('some other data'), 'f': f1.eid, 'dn': u'bar.jpg', 'df': u'image/jpeg'})
self.rollback()
@@ -241,9 +241,9 @@
new_path = self.fspath(f2)
new_data = f2.data.getvalue()
self.failUnless(osp.isfile(new_path))
- self.assertEquals(osp.splitext(new_path)[1], '.txt')
- self.assertEquals(old_path, new_path)
- self.assertEquals(old_data, new_data)
+ self.assertEqual(osp.splitext(new_path)[1], '.txt')
+ self.assertEqual(old_path, new_path)
+ self.assertEqual(old_data, new_data)
def test_bfss_update_with_fs_importing(self):
# use self.session to use server-side cache
@@ -256,8 +256,8 @@
self.execute('SET F data %(d)s WHERE F eid %(f)s',
{'d': Binary(new_fspath), 'f': f1.eid})
self.commit()
- self.assertEquals(f1.data.getvalue(), 'the new data')
- self.assertEquals(self.fspath(f1), new_fspath)
+ self.assertEqual(f1.data.getvalue(), 'the new data')
+ self.assertEqual(self.fspath(f1), new_fspath)
self.failIf(osp.isfile(old_fspath))
--- a/server/test/unittest_undo.py Thu Sep 23 23:28:58 2010 +0200
+++ b/server/test/unittest_undo.py Wed Sep 29 16:16:32 2010 +0200
@@ -54,36 +54,36 @@
self.cnx.undo_transaction, 'hop')
txinfo = self.cnx.transaction_info(self.txuuid)
self.failUnless(txinfo.datetime)
- self.assertEquals(txinfo.user_eid, self.session.user.eid)
- self.assertEquals(txinfo.user().login, 'admin')
+ self.assertEqual(txinfo.user_eid, self.session.user.eid)
+ self.assertEqual(txinfo.user().login, 'admin')
actions = txinfo.actions_list()
- self.assertEquals(len(actions), 2)
+ self.assertEqual(len(actions), 2)
actions = txinfo.actions_list(public=False)
- self.assertEquals(len(actions), 6)
+ self.assertEqual(len(actions), 6)
a1 = actions[0]
- self.assertEquals(a1.action, 'C')
- self.assertEquals(a1.eid, self.toto.eid)
- self.assertEquals(a1.etype,'CWUser')
- self.assertEquals(a1.changes, None)
- self.assertEquals(a1.public, True)
- self.assertEquals(a1.order, 1)
+ self.assertEqual(a1.action, 'C')
+ self.assertEqual(a1.eid, self.toto.eid)
+ self.assertEqual(a1.etype,'CWUser')
+ self.assertEqual(a1.changes, None)
+ self.assertEqual(a1.public, True)
+ self.assertEqual(a1.order, 1)
a4 = actions[3]
- self.assertEquals(a4.action, 'A')
- self.assertEquals(a4.rtype, 'in_group')
- self.assertEquals(a4.eid_from, self.toto.eid)
- self.assertEquals(a4.eid_to, self.toto.in_group[0].eid)
- self.assertEquals(a4.order, 4)
+ self.assertEqual(a4.action, 'A')
+ self.assertEqual(a4.rtype, 'in_group')
+ self.assertEqual(a4.eid_from, self.toto.eid)
+ self.assertEqual(a4.eid_to, self.toto.in_group[0].eid)
+ self.assertEqual(a4.order, 4)
for i, rtype in ((1, 'owned_by'), (2, 'owned_by'),
(4, 'in_state'), (5, 'created_by')):
a = actions[i]
- self.assertEquals(a.action, 'A')
- self.assertEquals(a.eid_from, self.toto.eid)
- self.assertEquals(a.rtype, rtype)
- self.assertEquals(a.order, i+1)
+ self.assertEqual(a.action, 'A')
+ self.assertEqual(a.eid_from, self.toto.eid)
+ self.assertEqual(a.rtype, rtype)
+ self.assertEqual(a.order, i+1)
# test undoable_transactions
txs = self.cnx.undoable_transactions()
- self.assertEquals(len(txs), 1)
- self.assertEquals(txs[0].uuid, self.txuuid)
+ self.assertEqual(len(txs), 1)
+ self.assertEqual(txs[0].uuid, self.txuuid)
# test transaction_info / undoable_transactions security
cnx = self.login('anon')
self.assertRaises(NoSuchTransaction,
@@ -93,7 +93,7 @@
self.assertRaises(NoSuchTransaction,
cnx.undo_transaction, self.txuuid)
txs = cnx.undoable_transactions()
- self.assertEquals(len(txs), 0)
+ self.assertEqual(len(txs), 0)
def test_undoable_transactions(self):
toto = self.toto
@@ -105,31 +105,31 @@
txuuid2 = self.commit()
undoable_transactions = self.cnx.undoable_transactions
txs = undoable_transactions(action='D')
- self.assertEquals(len(txs), 1, txs)
- self.assertEquals(txs[0].uuid, txuuid2)
+ self.assertEqual(len(txs), 1, txs)
+ self.assertEqual(txs[0].uuid, txuuid2)
txs = undoable_transactions(action='C')
- self.assertEquals(len(txs), 2, txs)
- self.assertEquals(txs[0].uuid, txuuid1)
- self.assertEquals(txs[1].uuid, self.txuuid)
+ self.assertEqual(len(txs), 2, txs)
+ self.assertEqual(txs[0].uuid, txuuid1)
+ self.assertEqual(txs[1].uuid, self.txuuid)
txs = undoable_transactions(eid=toto.eid)
- self.assertEquals(len(txs), 3)
- self.assertEquals(txs[0].uuid, txuuid2)
- self.assertEquals(txs[1].uuid, txuuid1)
- self.assertEquals(txs[2].uuid, self.txuuid)
+ self.assertEqual(len(txs), 3)
+ self.assertEqual(txs[0].uuid, txuuid2)
+ self.assertEqual(txs[1].uuid, txuuid1)
+ self.assertEqual(txs[2].uuid, self.txuuid)
txs = undoable_transactions(etype='CWUser')
- self.assertEquals(len(txs), 2)
+ self.assertEqual(len(txs), 2)
txs = undoable_transactions(etype='CWUser', action='C')
- self.assertEquals(len(txs), 1)
- self.assertEquals(txs[0].uuid, self.txuuid)
+ self.assertEqual(len(txs), 1)
+ self.assertEqual(txs[0].uuid, self.txuuid)
txs = undoable_transactions(etype='EmailAddress', action='D')
- self.assertEquals(len(txs), 0)
+ self.assertEqual(len(txs), 0)
txs = undoable_transactions(etype='EmailAddress', action='D',
public=False)
- self.assertEquals(len(txs), 1)
- self.assertEquals(txs[0].uuid, txuuid2)
+ self.assertEqual(len(txs), 1)
+ self.assertEqual(txs[0].uuid, txuuid2)
txs = undoable_transactions(eid=toto.eid, action='R', public=False)
- self.assertEquals(len(txs), 1)
- self.assertEquals(txs[0].uuid, txuuid2)
+ self.assertEqual(len(txs), 1)
+ self.assertEqual(txs[0].uuid, txuuid2)
def test_undo_deletion_base(self):
toto = self.toto
@@ -143,34 +143,34 @@
for_user=toto)
self.commit()
txs = self.cnx.undoable_transactions()
- self.assertEquals(len(txs), 2)
+ self.assertEqual(len(txs), 2)
toto.cw_delete()
txuuid = self.commit()
actions = self.cnx.transaction_info(txuuid).actions_list()
- self.assertEquals(len(actions), 1)
+ self.assertEqual(len(actions), 1)
toto.clear_all_caches()
e.clear_all_caches()
errors = self.cnx.undo_transaction(txuuid)
undotxuuid = self.commit()
- self.assertEquals(undotxuuid, None) # undo not undoable
- self.assertEquals(errors, [])
+ self.assertEqual(undotxuuid, None) # undo not undoable
+ self.assertEqual(errors, [])
self.failUnless(self.execute('Any X WHERE X eid %(x)s', {'x': toto.eid}))
self.failUnless(self.execute('Any X WHERE X eid %(x)s', {'x': e.eid}))
self.failUnless(self.execute('Any X WHERE X has_text "toto@logilab"'))
- self.assertEquals(toto.cw_adapt_to('IWorkflowable').state, 'activated')
- self.assertEquals(toto.cw_adapt_to('IEmailable').get_email(), 'toto@logilab.org')
- self.assertEquals([(p.pkey, p.value) for p in toto.reverse_for_user],
+ self.assertEqual(toto.cw_adapt_to('IWorkflowable').state, 'activated')
+ self.assertEqual(toto.cw_adapt_to('IEmailable').get_email(), 'toto@logilab.org')
+ self.assertEqual([(p.pkey, p.value) for p in toto.reverse_for_user],
[('ui.default-text-format', 'text/rest')])
- self.assertEquals([g.name for g in toto.in_group],
+ self.assertEqual([g.name for g in toto.in_group],
['users'])
- self.assertEquals([et.name for et in toto.related('is', entities=True)],
+ self.assertEqual([et.name for et in toto.related('is', entities=True)],
['CWUser'])
- self.assertEquals([et.name for et in toto.is_instance_of],
+ self.assertEqual([et.name for et in toto.is_instance_of],
['CWUser'])
# undoing shouldn't be visble in undoable transaction, and the undoed
# transaction should be removed
txs = self.cnx.undoable_transactions()
- self.assertEquals(len(txs), 2)
+ self.assertEqual(len(txs), 2)
self.assertRaises(NoSuchTransaction,
self.cnx.transaction_info, txuuid)
self.check_transaction_deleted(txuuid)
@@ -191,9 +191,9 @@
errors = self.cnx.undo_transaction(txuuid)
self.commit()
p.clear_all_caches()
- self.assertEquals(p.fiche[0].eid, c2.eid)
- self.assertEquals(len(errors), 1)
- self.assertEquals(errors[0],
+ self.assertEqual(p.fiche[0].eid, c2.eid)
+ self.assertEqual(len(errors), 1)
+ self.assertEqual(errors[0],
"Can't restore object relation fiche to entity "
"%s which is already linked using this relation." % p.eid)
@@ -209,12 +209,12 @@
g.cw_delete()
self.commit()
errors = self.cnx.undo_transaction(txuuid)
- self.assertEquals(errors,
+ self.assertEqual(errors,
[u"Can't restore relation in_group, object entity "
"%s doesn't exist anymore." % g.eid])
ex = self.assertRaises(ValidationError, self.commit)
- self.assertEquals(ex.entity, self.toto.eid)
- self.assertEquals(ex.errors,
+ self.assertEqual(ex.entity, self.toto.eid)
+ self.assertEqual(ex.errors,
{'in_group-subject': u'at least one relation in_group is '
'required on CWUser (%s)' % self.toto.eid})
@@ -254,8 +254,8 @@
self.commit()
ex = self.assertRaises(ValidationError,
self.cnx.undo_transaction, txuuid)
- self.assertEquals(ex.entity, tutu.eid)
- self.assertEquals(ex.errors,
+ self.assertEqual(ex.entity, tutu.eid)
+ self.assertEqual(ex.errors,
{None: 'some later transaction(s) touch entity, undo them first'})
def test_undo_creation_integrity_2(self):
@@ -267,15 +267,15 @@
self.commit()
ex = self.assertRaises(ValidationError,
self.cnx.undo_transaction, txuuid)
- self.assertEquals(ex.entity, g.eid)
- self.assertEquals(ex.errors,
+ self.assertEqual(ex.entity, g.eid)
+ self.assertEqual(ex.errors,
{None: 'some later transaction(s) touch entity, undo them first'})
- # self.assertEquals(errors,
+ # self.assertEqual(errors,
# [u"Can't restore relation in_group, object entity "
# "%s doesn't exist anymore." % g.eid])
# ex = self.assertRaises(ValidationError, self.commit)
- # self.assertEquals(ex.entity, self.toto.eid)
- # self.assertEquals(ex.errors,
+ # self.assertEqual(ex.entity, self.toto.eid)
+ # self.assertEqual(ex.errors,
# {'in_group-subject': u'at least one relation in_group is '
# 'required on CWUser (%s)' % self.toto.eid})
--- a/sobjects/test/unittest_email.py Thu Sep 23 23:28:58 2010 +0200
+++ b/sobjects/test/unittest_email.py Wed Sep 29 16:16:32 2010 +0200
@@ -26,23 +26,23 @@
def test_use_email_set_primary_email(self):
self.execute('INSERT EmailAddress X: X address "admin@logilab.fr", U use_email X WHERE U login "admin"')
- self.assertEquals(self.execute('Any A WHERE U primary_email X, U login "admin", X address A').rows,
+ self.assertEqual(self.execute('Any A WHERE U primary_email X, U login "admin", X address A').rows,
[])
self.commit()
- self.assertEquals(self.execute('Any A WHERE U primary_email X, U login "admin", X address A')[0][0],
+ self.assertEqual(self.execute('Any A WHERE U primary_email X, U login "admin", X address A')[0][0],
'admin@logilab.fr')
# having another email should'nt change anything
self.execute('INSERT EmailAddress X: X address "a@logilab.fr", U use_email X WHERE U login "admin"')
self.commit()
- self.assertEquals(self.execute('Any A WHERE U primary_email X, U login "admin", X address A')[0][0],
+ self.assertEqual(self.execute('Any A WHERE U primary_email X, U login "admin", X address A')[0][0],
'admin@logilab.fr')
def test_primary_email_set_use_email(self):
self.execute('INSERT EmailAddress X: X address "admin@logilab.fr", U primary_email X WHERE U login "admin"')
- self.assertEquals(self.execute('Any A WHERE U use_email X, U login "admin", X address A').rows,
+ self.assertEqual(self.execute('Any A WHERE U use_email X, U login "admin", X address A').rows,
[])
self.commit()
- self.assertEquals(self.execute('Any A WHERE U use_email X, U login "admin", X address A')[0][0],
+ self.assertEqual(self.execute('Any A WHERE U use_email X, U login "admin", X address A')[0][0],
'admin@logilab.fr')
def test_cardinality_check(self):
--- a/sobjects/test/unittest_notification.py Thu Sep 23 23:28:58 2010 +0200
+++ b/sobjects/test/unittest_notification.py Wed Sep 29 16:16:32 2010 +0200
@@ -72,12 +72,12 @@
finder = self.vreg['components'].select('recipients_finder',
self.request(), rset=urset)
self.set_option('default-recipients-mode', 'none')
- self.assertEquals(finder.recipients(), [])
+ self.assertEqual(finder.recipients(), [])
self.set_option('default-recipients-mode', 'users')
- self.assertEquals(finder.recipients(), [(u'admin@logilab.fr', 'fr')])
+ self.assertEqual(finder.recipients(), [(u'admin@logilab.fr', 'fr')])
self.set_option('default-recipients-mode', 'default-dest-addrs')
self.set_option('default-dest-addrs', 'abcd@logilab.fr, efgh@logilab.fr')
- self.assertEquals(finder.recipients(), [('abcd@logilab.fr', 'en'), ('efgh@logilab.fr', 'en')])
+ self.assertEqual(finder.recipients(), [('abcd@logilab.fr', 'en'), ('efgh@logilab.fr', 'en')])
class StatusChangeViewsTC(CubicWebTC):
@@ -88,9 +88,9 @@
u.cw_adapt_to('IWorkflowable').fire_transition('deactivate', comment=u'yeah')
self.failIf(MAILBOX)
self.commit()
- self.assertEquals(len(MAILBOX), 1)
+ self.assertEqual(len(MAILBOX), 1)
email = MAILBOX[0]
- self.assertEquals(email.content,
+ self.assertEqual(email.content,
'''
admin changed status from <activated> to <deactivated> for entity
'toto'
@@ -99,7 +99,7 @@
url: http://testing.fr/cubicweb/cwuser/toto
''')
- self.assertEquals(email.subject, 'status changed cwuser #%s (admin)' % u.eid)
+ self.assertEqual(email.subject, 'status changed cwuser #%s (admin)' % u.eid)
if __name__ == '__main__':
unittest_main()
--- a/sobjects/test/unittest_supervising.py Thu Sep 23 23:28:58 2010 +0200
+++ b/sobjects/test/unittest_supervising.py Wed Sep 29 16:16:32 2010 +0200
@@ -52,16 +52,16 @@
session = self.session
sentops = [op for op in session.pending_operations
if isinstance(op, SupervisionMailOp)]
- self.assertEquals(len(sentops), 1)
+ self.assertEqual(len(sentops), 1)
# check view content
op = sentops[0]
view = sentops[0]._get_view()
- self.assertEquals(view.recipients(), ['test@logilab.fr'])
- self.assertEquals(view.subject(), '[data supervision] changes summary')
+ self.assertEqual(view.recipients(), ['test@logilab.fr'])
+ self.assertEqual(view.subject(), '[data supervision] changes summary')
data = view.render(changes=session.transaction_data.get('pendingchanges')).strip()
data = re.sub('#\d+', '#EID', data)
data = re.sub('/\d+', '/EID', data)
- self.assertTextEquals('''user admin has made the following change(s):
+ self.assertMultiLineEqual('''user admin has made the following change(s):
* added cwuser #EID (toto)
http://testing.fr/cubicweb/cwuser/toto
@@ -79,22 +79,22 @@
data)
# check prepared email
op._prepare_email()
- self.assertEquals(len(op.to_send), 1)
+ self.assertEqual(len(op.to_send), 1)
self.assert_(op.to_send[0][0])
- self.assertEquals(op.to_send[0][1], ['test@logilab.fr'])
+ self.assertEqual(op.to_send[0][1], ['test@logilab.fr'])
self.commit()
# some other changes #######
user.cw_adapt_to('IWorkflowable').fire_transition('deactivate')
sentops = [op for op in session.pending_operations
if isinstance(op, SupervisionMailOp)]
- self.assertEquals(len(sentops), 1)
+ self.assertEqual(len(sentops), 1)
# check view content
op = sentops[0]
view = sentops[0]._get_view()
data = view.render(changes=session.transaction_data.get('pendingchanges')).strip()
data = re.sub('#\d+', '#EID', data)
data = re.sub('/\d+', '/EID', data)
- self.assertTextEquals('''user admin has made the following change(s):
+ self.assertMultiLineEqual('''user admin has made the following change(s):
* changed state of cwuser #EID (toto)
from state activated to state deactivated
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/data/cubes/email/entities.py Wed Sep 29 16:16:32 2010 +0200
@@ -0,0 +1,1 @@
+"test"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/data/cubes/email/hooks.py Wed Sep 29 16:16:32 2010 +0200
@@ -0,0 +1,1 @@
+"test"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/data/cubes/email/views/__init__.py Wed Sep 29 16:16:32 2010 +0200
@@ -0,0 +1,1 @@
+"test"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/data/cubes/file/entities/__init__.py Wed Sep 29 16:16:32 2010 +0200
@@ -0,0 +1,1 @@
+"test"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/data/cubes/file/hooks/__init__.py Wed Sep 29 16:16:32 2010 +0200
@@ -0,0 +1,1 @@
+"test"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/data/cubes/file/views.py Wed Sep 29 16:16:32 2010 +0200
@@ -0,0 +1,1 @@
+"test"
--- a/test/data/rewrite/bootstrap_cubes Thu Sep 23 23:28:58 2010 +0200
+++ b/test/data/rewrite/bootstrap_cubes Wed Sep 29 16:16:32 2010 +0200
@@ -1,1 +1,1 @@
-card, person
+card
--- a/test/data/rewrite/schema.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/data/rewrite/schema.py Wed Sep 29 16:16:32 2010 +0200
@@ -49,7 +49,7 @@
class require_permission(RelationDefinition):
- subject = ('Card', 'Note', 'Person')
+ subject = ('Card', 'Note')
object = 'CWPermission'
--- a/test/unittest_cwconfig.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_cwconfig.py Wed Sep 29 16:16:32 2010 +0200
@@ -54,17 +54,17 @@
self.config.adjust_sys_path()
# forge depends on email and file and comment
# email depends on file
- self.assertEquals(self.config.reorder_cubes(['file', 'email', 'forge']),
+ self.assertEqual(self.config.reorder_cubes(['file', 'email', 'forge']),
('forge', 'email', 'file'))
- self.assertEquals(self.config.reorder_cubes(['email', 'file', 'forge']),
+ self.assertEqual(self.config.reorder_cubes(['email', 'file', 'forge']),
('forge', 'email', 'file'))
- self.assertEquals(self.config.reorder_cubes(['email', 'forge', 'file']),
+ self.assertEqual(self.config.reorder_cubes(['email', 'forge', 'file']),
('forge', 'email', 'file'))
- self.assertEquals(self.config.reorder_cubes(['file', 'forge', 'email']),
+ self.assertEqual(self.config.reorder_cubes(['file', 'forge', 'email']),
('forge', 'email', 'file'))
- self.assertEquals(self.config.reorder_cubes(['forge', 'file', 'email']),
+ self.assertEqual(self.config.reorder_cubes(['forge', 'file', 'email']),
('forge', 'email', 'file'))
- self.assertEquals(self.config.reorder_cubes(('forge', 'email', 'file')),
+ self.assertEqual(self.config.reorder_cubes(('forge', 'email', 'file')),
('forge', 'email', 'file'))
def test_reorder_cubes_recommends(self):
@@ -75,13 +75,13 @@
try:
# email recommends comment
# comment recommends file
- self.assertEquals(self.config.reorder_cubes(('forge', 'email', 'file', 'comment')),
+ self.assertEqual(self.config.reorder_cubes(('forge', 'email', 'file', 'comment')),
('forge', 'email', 'comment', 'file'))
- self.assertEquals(self.config.reorder_cubes(('forge', 'email', 'comment', 'file')),
+ self.assertEqual(self.config.reorder_cubes(('forge', 'email', 'comment', 'file')),
('forge', 'email', 'comment', 'file'))
- self.assertEquals(self.config.reorder_cubes(('forge', 'comment', 'email', 'file')),
+ self.assertEqual(self.config.reorder_cubes(('forge', 'comment', 'email', 'file')),
('forge', 'email', 'comment', 'file'))
- self.assertEquals(self.config.reorder_cubes(('comment', 'forge', 'email', 'file')),
+ self.assertEqual(self.config.reorder_cubes(('comment', 'forge', 'email', 'file')),
('forge', 'email', 'comment', 'file'))
finally:
comment_pkginfo.__recommends_cubes__ = {}
@@ -90,19 +90,23 @@
# def test_vc_config(self):
# vcconf = self.config.vc_config()
# self.assertIsInstance(vcconf['EEMAIL'], Version)
-# self.assertEquals(vcconf['EEMAIL'], (0, 3, 1))
-# self.assertEquals(vcconf['CW'], (2, 31, 2))
+# self.assertEqual(vcconf['EEMAIL'], (0, 3, 1))
+# self.assertEqual(vcconf['CW'], (2, 31, 2))
# self.assertRaises(KeyError, vcconf.__getitem__, 'CW_VERSION')
# self.assertRaises(KeyError, vcconf.__getitem__, 'CRM')
def test_expand_cubes(self):
- self.assertEquals(self.config.expand_cubes(('email', 'blog')),
+ self.config.__class__.CUBES_PATH = [CUSTOM_CUBES_DIR]
+ self.config.adjust_sys_path()
+ self.assertEqual(self.config.expand_cubes(('email', 'blog')),
['email', 'blog', 'file'])
def test_vregistry_path(self):
- self.assertEquals([unabsolutize(p) for p in self.config.vregistry_path()],
+ self.config.__class__.CUBES_PATH = [CUSTOM_CUBES_DIR]
+ self.config.adjust_sys_path()
+ self.assertEqual([unabsolutize(p) for p in self.config.vregistry_path()],
['entities', 'web/views', 'sobjects', 'hooks',
- 'file/entities.py', 'file/views', 'file/hooks.py',
+ 'file/entities', 'file/views.py', 'file/hooks',
'email/entities.py', 'email/views', 'email/hooks.py',
'test/data/entities.py', 'test/data/views.py'])
@@ -111,27 +115,27 @@
import email
self.assertNotEquals(dirname(email.__file__), self.config.CUBES_DIR)
self.config.__class__.CUBES_PATH = [CUSTOM_CUBES_DIR]
- self.assertEquals(self.config.cubes_search_path(),
+ self.assertEqual(self.config.cubes_search_path(),
[CUSTOM_CUBES_DIR, self.config.CUBES_DIR])
self.config.__class__.CUBES_PATH = [CUSTOM_CUBES_DIR,
self.config.CUBES_DIR, 'unexistant']
# filter out unexistant and duplicates
- self.assertEquals(self.config.cubes_search_path(),
+ self.assertEqual(self.config.cubes_search_path(),
[CUSTOM_CUBES_DIR,
self.config.CUBES_DIR])
self.failUnless('mycube' in self.config.available_cubes())
# test cubes python path
self.config.adjust_sys_path()
import cubes
- self.assertEquals(cubes.__path__, self.config.cubes_search_path())
+ self.assertEqual(cubes.__path__, self.config.cubes_search_path())
# this import should succeed once path is adjusted
from cubes import mycube
- self.assertEquals(mycube.__path__, [join(CUSTOM_CUBES_DIR, 'mycube')])
+ self.assertEqual(mycube.__path__, [join(CUSTOM_CUBES_DIR, 'mycube')])
# file cube should be overriden by the one found in data/cubes
sys.modules.pop('cubes.file', None)
del cubes.file
from cubes import file
- self.assertEquals(file.__path__, [join(CUSTOM_CUBES_DIR, 'file')])
+ self.assertEqual(file.__path__, [join(CUSTOM_CUBES_DIR, 'file')])
class FindPrefixTC(TestCase):
@@ -153,35 +157,35 @@
def test_samedir(self):
prefix = tempfile.tempdir
self.make_dirs('share', 'cubicweb')
- self.assertEquals(_find_prefix(prefix), prefix)
+ self.assertEqual(_find_prefix(prefix), prefix)
@with_tempdir
def test_samedir_filepath(self):
prefix = tempfile.tempdir
self.make_dirs('share', 'cubicweb')
file_path = self.make_file('bob.py')
- self.assertEquals(_find_prefix(file_path), prefix)
+ self.assertEqual(_find_prefix(file_path), prefix)
@with_tempdir
def test_dir_inside_prefix(self):
prefix = tempfile.tempdir
self.make_dirs('share', 'cubicweb')
dir_path = self.make_dirs('bob')
- self.assertEquals(_find_prefix(dir_path), prefix)
+ self.assertEqual(_find_prefix(dir_path), prefix)
@with_tempdir
def test_file_in_dir_inside_prefix(self):
prefix = tempfile.tempdir
self.make_dirs('share', 'cubicweb')
file_path = self.make_file('bob', 'toto.py')
- self.assertEquals(_find_prefix(file_path), prefix)
+ self.assertEqual(_find_prefix(file_path), prefix)
@with_tempdir
def test_file_in_deeper_dir_inside_prefix(self):
prefix = tempfile.tempdir
self.make_dirs('share', 'cubicweb')
file_path = self.make_file('bob', 'pyves', 'alain', 'adim', 'syt', 'toto.py')
- self.assertEquals(_find_prefix(file_path), prefix)
+ self.assertEqual(_find_prefix(file_path), prefix)
@with_tempdir
def test_multiple_candidate_prefix(self):
@@ -189,7 +193,7 @@
prefix = self.make_dirs('bob')
self.make_dirs('bob', 'share', 'cubicweb')
file_path = self.make_file('bob', 'pyves', 'alain', 'adim', 'syt', 'toto.py')
- self.assertEquals(_find_prefix(file_path), prefix)
+ self.assertEqual(_find_prefix(file_path), prefix)
@with_tempdir
def test_sister_candidate_prefix(self):
@@ -197,7 +201,7 @@
self.make_dirs('share', 'cubicweb')
self.make_dirs('bob', 'share', 'cubicweb')
file_path = self.make_file('bell', 'toto.py')
- self.assertEquals(_find_prefix(file_path), prefix)
+ self.assertEqual(_find_prefix(file_path), prefix)
@with_tempdir
def test_multiple_parent_candidate_prefix(self):
@@ -205,7 +209,7 @@
prefix = self.make_dirs('share', 'cubicweb', 'bob')
self.make_dirs('share', 'cubicweb', 'bob', 'share', 'cubicweb')
file_path = self.make_file('share', 'cubicweb', 'bob', 'pyves', 'alain', 'adim', 'syt', 'toto.py')
- self.assertEquals(_find_prefix(file_path), prefix)
+ self.assertEqual(_find_prefix(file_path), prefix)
@with_tempdir
def test_upper_candidate_prefix(self):
@@ -213,12 +217,12 @@
self.make_dirs('share', 'cubicweb')
self.make_dirs('bell','bob', 'share', 'cubicweb')
file_path = self.make_file('bell', 'toto.py')
- self.assertEquals(_find_prefix(file_path), prefix)
+ self.assertEqual(_find_prefix(file_path), prefix)
@with_tempdir
def test_no_prefix(self):
prefix = tempfile.tempdir
- self.assertEquals(_find_prefix(prefix), sys.prefix)
+ self.assertEqual(_find_prefix(prefix), sys.prefix)
if __name__ == '__main__':
unittest_main()
--- a/test/unittest_dbapi.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_dbapi.py Wed Sep 29 16:16:32 2010 +0200
@@ -29,40 +29,40 @@
def test_public_repo_api(self):
cnx = self.login('anon')
- self.assertEquals(cnx.get_schema(), self.repo.schema)
- self.assertEquals(cnx.source_defs(), {'system': {'adapter': 'native', 'uri': 'system'}})
+ self.assertEqual(cnx.get_schema(), self.repo.schema)
+ self.assertEqual(cnx.source_defs(), {'system': {'adapter': 'native', 'uri': 'system'}})
self.restore_connection() # proper way to close cnx
self.assertRaises(ProgrammingError, cnx.get_schema)
self.assertRaises(ProgrammingError, cnx.source_defs)
def test_db_api(self):
cnx = self.login('anon')
- self.assertEquals(cnx.rollback(), None)
- self.assertEquals(cnx.commit(), None)
+ self.assertEqual(cnx.rollback(), None)
+ self.assertEqual(cnx.commit(), None)
self.restore_connection() # proper way to close cnx
- #self.assertEquals(cnx.close(), None)
+ #self.assertEqual(cnx.close(), None)
self.assertRaises(ProgrammingError, cnx.rollback)
self.assertRaises(ProgrammingError, cnx.commit)
self.assertRaises(ProgrammingError, cnx.close)
def test_api(self):
cnx = self.login('anon')
- self.assertEquals(cnx.user(None).login, 'anon')
- self.assertEquals(cnx.describe(1), (u'CWGroup', u'system', None))
+ self.assertEqual(cnx.user(None).login, 'anon')
+ self.assertEqual(cnx.describe(1), (u'CWGroup', u'system', None))
self.restore_connection() # proper way to close cnx
self.assertRaises(ProgrammingError, cnx.user, None)
self.assertRaises(ProgrammingError, cnx.describe, 1)
def test_shared_data_api(self):
cnx = self.login('anon')
- self.assertEquals(cnx.get_shared_data('data'), None)
+ self.assertEqual(cnx.get_shared_data('data'), None)
cnx.set_shared_data('data', 4)
- self.assertEquals(cnx.get_shared_data('data'), 4)
+ self.assertEqual(cnx.get_shared_data('data'), 4)
cnx.get_shared_data('data', pop=True)
cnx.get_shared_data('whatever', pop=True)
- self.assertEquals(cnx.get_shared_data('data'), None)
+ self.assertEqual(cnx.get_shared_data('data'), None)
cnx.set_shared_data('data', 4)
- self.assertEquals(cnx.get_shared_data('data'), 4)
+ self.assertEqual(cnx.get_shared_data('data'), 4)
self.restore_connection() # proper way to close cnx
self.assertRaises(ProgrammingError, cnx.check)
self.assertRaises(ProgrammingError, cnx.set_shared_data, 'data', 0)
--- a/test/unittest_entity.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_entity.py Wed Sep 29 16:16:32 2010 +0200
@@ -40,14 +40,14 @@
def test_has_eid(self):
e = self.vreg['etypes'].etype_class('CWUser')(self.request())
- self.assertEquals(e.eid, None)
- self.assertEquals(e.has_eid(), False)
+ self.assertEqual(e.eid, None)
+ self.assertEqual(e.has_eid(), False)
e.eid = 'X'
- self.assertEquals(e.has_eid(), False)
+ self.assertEqual(e.has_eid(), False)
e.eid = 0
- self.assertEquals(e.has_eid(), True)
+ self.assertEqual(e.has_eid(), True)
e.eid = 2
- self.assertEquals(e.has_eid(), True)
+ self.assertEqual(e.has_eid(), True)
def test_copy(self):
req = self.request()
@@ -59,11 +59,11 @@
self.execute('SET TAG tags X WHERE X eid %(x)s', {'x': oe.eid})
e = req.create_entity('Note', type=u'z')
e.copy_relations(oe.eid)
- self.assertEquals(len(e.ecrit_par), 1)
- self.assertEquals(e.ecrit_par[0].eid, p.eid)
- self.assertEquals(len(e.reverse_tags), 1)
+ self.assertEqual(len(e.ecrit_par), 1)
+ self.assertEqual(e.ecrit_par[0].eid, p.eid)
+ self.assertEqual(len(e.reverse_tags), 1)
# check meta-relations are not copied, set on commit
- self.assertEquals(len(e.created_by), 0)
+ self.assertEqual(len(e.created_by), 0)
def test_copy_with_nonmeta_composite_inlined(self):
req = self.request()
@@ -81,8 +81,8 @@
user = self.user()
adeleid = self.execute('INSERT EmailAddress X: X address "toto@logilab.org", U use_email X WHERE U login "admin"')[0][0]
e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
- self.assertEquals(e.use_email[0].address, "toto@logilab.org")
- self.assertEquals(e.use_email[0].eid, adeleid)
+ self.assertEqual(e.use_email[0].address, "toto@logilab.org")
+ self.assertEqual(e.use_email[0].eid, adeleid)
usereid = self.execute('INSERT CWUser X: X login "toto", X upassword "toto", X in_group G '
'WHERE G name "users"')[0][0]
e = self.execute('Any X WHERE X eid %(x)s', {'x': usereid}).get_entity(0, 0)
@@ -102,18 +102,18 @@
e.copy_relations(user.eid)
self.commit()
e.cw_clear_relation_cache('in_state', 'subject')
- self.assertEquals(e.cw_adapt_to('IWorkflowable').state, 'activated')
+ self.assertEqual(e.cw_adapt_to('IWorkflowable').state, 'activated')
def test_related_cache_both(self):
user = self.execute('Any X WHERE X eid %(x)s', {'x':self.user().eid}).get_entity(0, 0)
adeleid = self.execute('INSERT EmailAddress X: X address "toto@logilab.org", U use_email X WHERE U login "admin"')[0][0]
self.commit()
- self.assertEquals(user._cw_related_cache, {})
+ self.assertEqual(user._cw_related_cache, {})
email = user.primary_email[0]
- self.assertEquals(sorted(user._cw_related_cache), ['primary_email_subject'])
- self.assertEquals(email._cw_related_cache.keys(), ['primary_email_object'])
+ self.assertEqual(sorted(user._cw_related_cache), ['primary_email_subject'])
+ self.assertEqual(email._cw_related_cache.keys(), ['primary_email_object'])
groups = user.in_group
- self.assertEquals(sorted(user._cw_related_cache), ['in_group_subject', 'primary_email_subject'])
+ self.assertEqual(sorted(user._cw_related_cache), ['in_group_subject', 'primary_email_subject'])
for group in groups:
self.failIf('in_group_subject' in group._cw_related_cache, group._cw_related_cache.keys())
@@ -123,8 +123,8 @@
for tag in u'abcd':
req.create_entity('Tag', name=tag)
self.execute('SET X tags Y WHERE X is Tag, Y is Personne')
- self.assertEquals(len(p.related('tags', 'object', limit=2)), 2)
- self.assertEquals(len(p.related('tags', 'object')), 4)
+ self.assertEqual(len(p.related('tags', 'object', limit=2)), 2)
+ self.assertEqual(len(p.related('tags', 'object')), 4)
def test_fetch_rql(self):
@@ -139,7 +139,7 @@
peschema.subjrels['evaluee'].rdef(peschema, Note.e_schema).cardinality = '1*'
seschema.subjrels['evaluee'].rdef(seschema, Note.e_schema).cardinality = '1*'
# testing basic fetch_attrs attribute
- self.assertEquals(Personne.fetch_rql(user),
+ self.assertEqual(Personne.fetch_rql(user),
'Any X,AA,AB,AC ORDERBY AA ASC '
'WHERE X is Personne, X nom AA, X prenom AB, X modification_date AC')
pfetch_attrs = Personne.fetch_attrs
@@ -147,39 +147,39 @@
try:
# testing unknown attributes
Personne.fetch_attrs = ('bloug', 'beep')
- self.assertEquals(Personne.fetch_rql(user), 'Any X WHERE X is Personne')
+ self.assertEqual(Personne.fetch_rql(user), 'Any X WHERE X is Personne')
# testing one non final relation
Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
- self.assertEquals(Personne.fetch_rql(user),
+ self.assertEqual(Personne.fetch_rql(user),
'Any X,AA,AB,AC,AD ORDERBY AA ASC '
'WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD')
# testing two non final relations
Personne.fetch_attrs = ('nom', 'prenom', 'travaille', 'evaluee')
- self.assertEquals(Personne.fetch_rql(user),
+ self.assertEqual(Personne.fetch_rql(user),
'Any X,AA,AB,AC,AD,AE,AF ORDERBY AA ASC,AF DESC '
'WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD, '
'X evaluee AE?, AE modification_date AF')
# testing one non final relation with recursion
Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
Societe.fetch_attrs = ('nom', 'evaluee')
- self.assertEquals(Personne.fetch_rql(user),
+ self.assertEqual(Personne.fetch_rql(user),
'Any X,AA,AB,AC,AD,AE,AF ORDERBY AA ASC,AF DESC '
'WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD, '
'AC evaluee AE?, AE modification_date AF'
)
# testing symmetric relation
Personne.fetch_attrs = ('nom', 'connait')
- self.assertEquals(Personne.fetch_rql(user), 'Any X,AA,AB ORDERBY AA ASC '
+ self.assertEqual(Personne.fetch_rql(user), 'Any X,AA,AB ORDERBY AA ASC '
'WHERE X is Personne, X nom AA, X connait AB?')
# testing optional relation
peschema.subjrels['travaille'].rdef(peschema, seschema).cardinality = '?*'
Personne.fetch_attrs = ('nom', 'prenom', 'travaille')
Societe.fetch_attrs = ('nom',)
- self.assertEquals(Personne.fetch_rql(user),
+ self.assertEqual(Personne.fetch_rql(user),
'Any X,AA,AB,AC,AD ORDERBY AA ASC WHERE X is Personne, X nom AA, X prenom AB, X travaille AC?, AC nom AD')
# testing relation with cardinality > 1
peschema.subjrels['travaille'].rdef(peschema, seschema).cardinality = '**'
- self.assertEquals(Personne.fetch_rql(user),
+ self.assertEqual(Personne.fetch_rql(user),
'Any X,AA,AB ORDERBY AA ASC WHERE X is Personne, X nom AA, X prenom AB')
# XXX test unauthorized attribute
finally:
@@ -195,20 +195,20 @@
Note.fetch_attrs, Note.fetch_order = fetch_config(('type',))
SubNote.fetch_attrs, SubNote.fetch_order = fetch_config(('type',))
p = self.request().create_entity('Personne', nom=u'pouet')
- self.assertEquals(p.cw_related_rql('evaluee'),
+ self.assertEqual(p.cw_related_rql('evaluee'),
'Any X,AA,AB ORDERBY AA ASC WHERE E eid %(x)s, E evaluee X, '
'X type AA, X modification_date AB')
Personne.fetch_attrs, Personne.fetch_order = fetch_config(('nom', ))
# XXX
- self.assertEquals(p.cw_related_rql('evaluee'),
+ self.assertEqual(p.cw_related_rql('evaluee'),
'Any X,AA ORDERBY AA DESC '
'WHERE E eid %(x)s, E evaluee X, X modification_date AA')
tag = self.vreg['etypes'].etype_class('Tag')(self.request())
- self.assertEquals(tag.cw_related_rql('tags', 'subject'),
+ self.assertEqual(tag.cw_related_rql('tags', 'subject'),
'Any X,AA ORDERBY AA DESC '
'WHERE E eid %(x)s, E tags X, X modification_date AA')
- self.assertEquals(tag.cw_related_rql('tags', 'subject', ('Personne',)),
+ self.assertEqual(tag.cw_related_rql('tags', 'subject', ('Personne',)),
'Any X,AA,AB ORDERBY AA ASC '
'WHERE E eid %(x)s, E tags X, X is IN (Personne), X nom AA, '
'X modification_date AB')
@@ -217,20 +217,20 @@
tag = self.vreg['etypes'].etype_class('Tag')(self.request())
for ttype in self.schema['tags'].objects():
self.vreg['etypes'].etype_class(ttype).fetch_attrs = ('modification_date',)
- self.assertEquals(tag.cw_related_rql('tags', 'subject'),
+ self.assertEqual(tag.cw_related_rql('tags', 'subject'),
'Any X,AA ORDERBY AA DESC '
'WHERE E eid %(x)s, E tags X, X modification_date AA')
def test_unrelated_rql_security_1(self):
user = self.request().user
rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
- self.assertEquals(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
+ self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
'WHERE NOT S use_email O, S eid %(x)s, O is EmailAddress, O address AA, O alias AB, O modification_date AC')
self.create_user('toto')
self.login('toto')
user = self.request().user
rql = user.cw_unrelated_rql('use_email', 'EmailAddress', 'subject')[0]
- self.assertEquals(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
+ self.assertEqual(rql, 'Any O,AA,AB,AC ORDERBY AC DESC '
'WHERE NOT S use_email O, S eid %(x)s, O is EmailAddress, O address AA, O alias AB, O modification_date AC')
user = self.execute('Any X WHERE X login "admin"').get_entity(0, 0)
self.assertRaises(Unauthorized, user.cw_unrelated_rql, 'use_email', 'EmailAddress', 'subject')
@@ -241,24 +241,24 @@
def test_unrelated_rql_security_2(self):
email = self.execute('INSERT EmailAddress X: X address "hop"').get_entity(0, 0)
rql = email.cw_unrelated_rql('use_email', 'CWUser', 'object')[0]
- self.assertEquals(rql, 'Any S,AA,AB,AC,AD ORDERBY AA ASC '
+ self.assertEqual(rql, 'Any S,AA,AB,AC,AD ORDERBY AA ASC '
'WHERE NOT S use_email O, O eid %(x)s, S is CWUser, S login AA, S firstname AB, S surname AC, S modification_date AD')
#rql = email.cw_unrelated_rql('use_email', 'Person', 'object')[0]
- #self.assertEquals(rql, '')
+ #self.assertEqual(rql, '')
self.login('anon')
email = self.execute('Any X WHERE X eid %(x)s', {'x': email.eid}).get_entity(0, 0)
rql = email.cw_unrelated_rql('use_email', 'CWUser', 'object')[0]
- self.assertEquals(rql, 'Any S,AA,AB,AC,AD ORDERBY AA '
+ self.assertEqual(rql, 'Any S,AA,AB,AC,AD ORDERBY AA '
'WHERE NOT EXISTS(S use_email O), O eid %(x)s, S is CWUser, S login AA, S firstname AB, S surname AC, S modification_date AD, '
'A eid %(B)s, EXISTS(S identity A, NOT A in_group C, C name "guests", C is CWGroup)')
#rql = email.cw_unrelated_rql('use_email', 'Person', 'object')[0]
- #self.assertEquals(rql, '')
+ #self.assertEqual(rql, '')
def test_unrelated_rql_security_nonexistant(self):
self.login('anon')
email = self.vreg['etypes'].etype_class('EmailAddress')(self.request())
rql = email.cw_unrelated_rql('use_email', 'CWUser', 'object')[0]
- self.assertEquals(rql, 'Any S,AA,AB,AC,AD ORDERBY AA '
+ self.assertEqual(rql, 'Any S,AA,AB,AC,AD ORDERBY AA '
'WHERE S is CWUser, S login AA, S firstname AB, S surname AC, S modification_date AD, '
'A eid %(B)s, EXISTS(S identity A, NOT A in_group C, C name "guests", C is CWGroup)')
@@ -280,53 +280,53 @@
e = req.create_entity('Tag', name=u'x')
req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
req.create_entity('Personne', nom=u'thenault', prenom=u'sylvain')
- self.assertEquals(len(e.unrelated('tags', 'Personne', 'subject', limit=1)),
+ self.assertEqual(len(e.unrelated('tags', 'Personne', 'subject', limit=1)),
1)
def test_unrelated_security(self):
email = self.execute('INSERT EmailAddress X: X address "hop"').get_entity(0, 0)
rset = email.unrelated('use_email', 'CWUser', 'object')
- self.assertEquals([x.login for x in rset.entities()], [u'admin', u'anon'])
+ self.assertEqual([x.login for x in rset.entities()], [u'admin', u'anon'])
user = self.request().user
rset = user.unrelated('use_email', 'EmailAddress', 'subject')
- self.assertEquals([x.address for x in rset.entities()], [u'hop'])
+ self.assertEqual([x.address for x in rset.entities()], [u'hop'])
self.create_user('toto')
self.login('toto')
email = self.execute('Any X WHERE X eid %(x)s', {'x': email.eid}).get_entity(0, 0)
rset = email.unrelated('use_email', 'CWUser', 'object')
- self.assertEquals([x.login for x in rset.entities()], ['toto'])
+ self.assertEqual([x.login for x in rset.entities()], ['toto'])
user = self.request().user
rset = user.unrelated('use_email', 'EmailAddress', 'subject')
- self.assertEquals([x.address for x in rset.entities()], ['hop'])
+ self.assertEqual([x.address for x in rset.entities()], ['hop'])
user = self.execute('Any X WHERE X login "admin"').get_entity(0, 0)
rset = user.unrelated('use_email', 'EmailAddress', 'subject')
- self.assertEquals([x.address for x in rset.entities()], [])
+ self.assertEqual([x.address for x in rset.entities()], [])
self.login('anon')
email = self.execute('Any X WHERE X eid %(x)s', {'x': email.eid}).get_entity(0, 0)
rset = email.unrelated('use_email', 'CWUser', 'object')
- self.assertEquals([x.login for x in rset.entities()], [])
+ self.assertEqual([x.login for x in rset.entities()], [])
user = self.request().user
rset = user.unrelated('use_email', 'EmailAddress', 'subject')
- self.assertEquals([x.address for x in rset.entities()], [])
+ self.assertEqual([x.address for x in rset.entities()], [])
def test_unrelated_new_entity(self):
e = self.vreg['etypes'].etype_class('CWUser')(self.request())
unrelated = [r[0] for r in e.unrelated('in_group', 'CWGroup', 'subject')]
# should be default groups but owners, i.e. managers, users, guests
- self.assertEquals(len(unrelated), 3)
+ self.assertEqual(len(unrelated), 3)
def test_printable_value_string(self):
e = self.request().create_entity('Card', title=u'rest test', content=u'du :eid:`1:*ReST*`',
content_format=u'text/rest')
- self.assertEquals(e.printable_value('content'),
+ self.assertEqual(e.printable_value('content'),
'<p>du <a class="reference" href="http://testing.fr/cubicweb/cwgroup/guests">*ReST*</a></p>\n')
e.cw_attr_cache['content'] = 'du <em>html</em> <ref rql="CWUser X">users</ref>'
e.cw_attr_cache['content_format'] = 'text/html'
- self.assertEquals(e.printable_value('content'),
+ self.assertEqual(e.printable_value('content'),
'du <em>html</em> <a href="http://testing.fr/cubicweb/view?rql=CWUser%20X">users</a>')
e.cw_attr_cache['content'] = 'du *texte*'
e.cw_attr_cache['content_format'] = 'text/plain'
- self.assertEquals(e.printable_value('content'),
+ self.assertEqual(e.printable_value('content'),
'<p>\ndu *texte*<br/>\n</p>')
e.cw_attr_cache['title'] = 'zou'
e.cw_attr_cache['content'] = '''\
@@ -334,17 +334,16 @@
=======
du :eid:`1:*ReST*`'''
e.cw_attr_cache['content_format'] = 'text/rest'
- self.assertEquals(e.printable_value('content', format='text/plain'),
+ self.assertEqual(e.printable_value('content', format='text/plain'),
e.cw_attr_cache['content'])
e.cw_attr_cache['content'] = u'<b>yo (zou éà ;)</b>'
e.cw_attr_cache['content_format'] = 'text/html'
- self.assertEquals(e.printable_value('content', format='text/plain').strip(),
- u'**yo (zou éà ;)**')
+ self.assertEqual(e.printable_value('content', format='text/plain').strip(),
if HAS_TAL:
e.cw_attr_cache['content'] = '<h1 tal:content="self/title">titre</h1>'
e.cw_attr_cache['content_format'] = 'text/cubicweb-page-template'
- self.assertEquals(e.printable_value('content'),
+ self.assertEqual(e.printable_value('content'),
'<h1>zou</h1>')
@@ -356,17 +355,17 @@
if mttransforms.HAS_PYGMENTS_TRANSFORMS:
import pygments
if tuple(int(i) for i in pygments.__version__.split('.')[:2]) >= (1, 3):
- self.assertEquals(e.printable_value('data'),
+ self.assertEqual(e.printable_value('data'),
'''<div class="highlight"><pre><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="mi">1</span>
</pre></div>
''')
else:
- self.assertEquals(e.printable_value('data'),
+ self.assertEqual(e.printable_value('data'),
'''<div class="highlight"><pre><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="mf">1</span>
</pre></div>
''')
else:
- self.assertEquals(e.printable_value('data'),
+ self.assertEqual(e.printable_value('data'),
'''<pre class="python">
<span style="color: #C00000;">lambda</span> <span style="color: #000000;">x</span><span style="color: #0000C0;">:</span> <span style="color: #0080C0;">1</span>
</pre>
@@ -374,7 +373,7 @@
e = req.create_entity('File', data=Binary('*héhéhé*'), data_format=u'text/rest',
data_encoding=u'utf-8', data_name=u'toto.txt')
- self.assertEquals(e.printable_value('data'),
+ self.assertEqual(e.printable_value('data'),
u'<p><em>héhéhé</em></p>\n')
def test_printable_value_bad_html(self):
@@ -383,42 +382,43 @@
e = req.create_entity('Card', title=u'bad html', content=u'<div>R&D<br>',
content_format=u'text/html')
tidy = lambda x: x.replace('\n', '')
- self.assertEquals(tidy(e.printable_value('content')),
+ self.assertEqual(tidy(e.printable_value('content')),
'<div>R&D<br/></div>')
e.cw_attr_cache['content'] = u'yo !! R&D <div> pas fermé'
- self.assertEquals(tidy(e.printable_value('content')),
+ self.assertEqual(tidy(e.printable_value('content')),
u'yo !! R&D <div> pas fermé</div>')
e.cw_attr_cache['content'] = u'R&D'
- self.assertEquals(tidy(e.printable_value('content')), u'R&D')
+ self.assertEqual(tidy(e.printable_value('content')), u'R&D')
e.cw_attr_cache['content'] = u'R&D;'
- self.assertEquals(tidy(e.printable_value('content')), u'R&D;')
+ self.assertEqual(tidy(e.printable_value('content')), u'R&D;')
e.cw_attr_cache['content'] = u'yo !! R&D <div> pas fermé'
- self.assertEquals(tidy(e.printable_value('content')),
+ self.assertEqual(tidy(e.printable_value('content')),
u'yo !! R&D <div> pas fermé</div>')
e.cw_attr_cache['content'] = u'été <div> été'
- self.assertEquals(tidy(e.printable_value('content')),
- u'été <div> été</div>')
+ self.assertEqual(tidy(e.printable_value('content')),
e.cw_attr_cache['content'] = u'C'est un exemple sérieux'
- self.assertEquals(tidy(e.printable_value('content')),
+ self.assertEqual(tidy(e.printable_value('content')),
+ e['content'] = u'C'est un exemple sérieux'
+ self.assertEqual(tidy(e.printable_value('content')),
u"C'est un exemple sérieux")
# make sure valid xhtml is left untouched
e.cw_attr_cache['content'] = u'<div>R&D<br/></div>'
- self.assertEquals(e.printable_value('content'), e.cw_attr_cache['content'])
+ self.assertEqual(e.printable_value('content'), e.cw_attr_cache['content'])
e.cw_attr_cache['content'] = u'<div>été</div>'
- self.assertEquals(e.printable_value('content'), e.cw_attr_cache['content'])
+ self.assertEqual(e.printable_value('content'), e.cw_attr_cache['content'])
e.cw_attr_cache['content'] = u'été'
- self.assertEquals(e.printable_value('content'), e.cw_attr_cache['content'])
+ self.assertEqual(e.printable_value('content'), e.cw_attr_cache['content'])
e.cw_attr_cache['content'] = u'hop\r\nhop\nhip\rmomo'
- self.assertEquals(e.printable_value('content'), u'hop\nhop\nhip\nmomo')
+ self.assertEqual(e.printable_value('content'), u'hop\nhop\nhip\nmomo')
def test_printable_value_bad_html_ms(self):
- self.skip('fix soup2xhtml to handle this test')
+ self.skipTest('fix soup2xhtml to handle this test')
req = self.request()
e = req.create_entity('Card', title=u'bad html', content=u'<div>R&D<br>',
content_format=u'text/html')
tidy = lambda x: x.replace('\n', '')
e.cw_attr_cache['content'] = u'<div x:foo="bar">ms orifice produces weird html</div>'
- self.assertEquals(tidy(e.printable_value('content')),
+ self.assertEqual(tidy(e.printable_value('content')),
u'<div>ms orifice produces weird html</div>')
import tidy as tidymod # apt-get install python-tidy
tidy = lambda x: str(tidymod.parseString(x.encode('utf-8'),
@@ -427,7 +427,7 @@
'show_body_only' : True,
'quote-nbsp' : False,
'char_encoding' : 'utf8'})).decode('utf-8').strip()
- self.assertEquals(tidy(e.printable_value('content')),
+ self.assertEqual(tidy(e.printable_value('content')),
u'<div>ms orifice produces weird html</div>')
@@ -440,7 +440,7 @@
e.cw_attr_cache['data_format'] = 'text/html'
e.cw_attr_cache['data_encoding'] = 'ascii'
e._cw.transaction_data = {} # XXX req should be a session
- self.assertEquals(e.cw_adapt_to('IFTIndexable').get_words(),
+ self.assertEqual(e.cw_adapt_to('IFTIndexable').get_words(),
{'C': [u'du', u'html', 'an', 'html', 'file', u'some', u'data']})
@@ -449,7 +449,7 @@
p1 = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
p2 = req.create_entity('Personne', nom=u'toto')
self.execute('SET X evaluee Y WHERE X nom "di mascio", Y nom "toto"')
- self.assertEquals(p1.evaluee[0].nom, "toto")
+ self.assertEqual(p1.evaluee[0].nom, "toto")
self.failUnless(not p1.reverse_evaluee)
def test_complete_relation(self):
@@ -463,7 +463,7 @@
self.failUnless(trinfo.cw_relation_cached('from_state', 'subject'))
self.failUnless(trinfo.cw_relation_cached('to_state', 'subject'))
self.failUnless(trinfo.cw_relation_cached('wf_info_for', 'subject'))
- self.assertEquals(trinfo.by_transition, ())
+ self.assertEqual(trinfo.by_transition, ())
def test_request_cache(self):
req = self.request()
@@ -475,55 +475,55 @@
def test_rest_path(self):
req = self.request()
note = req.create_entity('Note', type=u'z')
- self.assertEquals(note.rest_path(), 'note/%s' % note.eid)
+ self.assertEqual(note.rest_path(), 'note/%s' % note.eid)
# unique attr
tag = req.create_entity('Tag', name=u'x')
- self.assertEquals(tag.rest_path(), 'tag/x')
+ self.assertEqual(tag.rest_path(), 'tag/x')
# test explicit rest_attr
person = req.create_entity('Personne', prenom=u'john', nom=u'doe')
- self.assertEquals(person.rest_path(), 'personne/doe')
+ self.assertEqual(person.rest_path(), 'personne/doe')
# ambiguity test
person2 = req.create_entity('Personne', prenom=u'remi', nom=u'doe')
person.clear_all_caches()
- self.assertEquals(person.rest_path(), 'personne/eid/%s' % person.eid)
- self.assertEquals(person2.rest_path(), 'personne/eid/%s' % person2.eid)
+ self.assertEqual(person.rest_path(), 'personne/eid/%s' % person.eid)
+ self.assertEqual(person2.rest_path(), 'personne/eid/%s' % person2.eid)
# unique attr with None value (wikiid in this case)
card1 = req.create_entity('Card', title=u'hop')
- self.assertEquals(card1.rest_path(), 'card/eid/%s' % card1.eid)
+ self.assertEqual(card1.rest_path(), 'card/eid/%s' % card1.eid)
# don't use rest if we have /, ? or & in the path (breaks mod_proxy)
card2 = req.create_entity('Card', title=u'pod', wikiid=u'zo/bi')
- self.assertEquals(card2.rest_path(), 'card/eid/%d' % card2.eid)
+ self.assertEqual(card2.rest_path(), 'card/eid/%d' % card2.eid)
card3 = req.create_entity('Card', title=u'pod', wikiid=u'zo&bi')
- self.assertEquals(card3.rest_path(), 'card/eid/%d' % card3.eid)
+ self.assertEqual(card3.rest_path(), 'card/eid/%d' % card3.eid)
card4 = req.create_entity('Card', title=u'pod', wikiid=u'zo?bi')
- self.assertEquals(card4.rest_path(), 'card/eid/%d' % card4.eid)
+ self.assertEqual(card4.rest_path(), 'card/eid/%d' % card4.eid)
def test_set_attributes(self):
req = self.request()
person = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
- self.assertEquals(person.prenom, u'adrien')
- self.assertEquals(person.nom, u'di mascio')
+ self.assertEqual(person.prenom, u'adrien')
+ self.assertEqual(person.nom, u'di mascio')
person.set_attributes(prenom=u'sylvain', nom=u'thénault')
person = self.execute('Personne P').get_entity(0, 0) # XXX retreival needed ?
- self.assertEquals(person.prenom, u'sylvain')
- self.assertEquals(person.nom, u'thénault')
+ self.assertEqual(person.prenom, u'sylvain')
+ self.assertEqual(person.nom, u'thénault')
def test_metainformation_and_external_absolute_url(self):
req = self.request()
note = req.create_entity('Note', type=u'z')
metainf = note.cw_metainformation()
- self.assertEquals(metainf, {'source': {'adapter': 'native', 'uri': 'system'}, 'type': u'Note', 'extid': None})
- self.assertEquals(note.absolute_url(), 'http://testing.fr/cubicweb/note/%s' % note.eid)
+ self.assertEqual(metainf, {'source': {'adapter': 'native', 'uri': 'system'}, 'type': u'Note', 'extid': None})
+ self.assertEqual(note.absolute_url(), 'http://testing.fr/cubicweb/note/%s' % note.eid)
metainf['source'] = metainf['source'].copy()
metainf['source']['base-url'] = 'http://cubicweb2.com/'
metainf['extid'] = 1234
- self.assertEquals(note.absolute_url(), 'http://cubicweb2.com/note/1234')
+ self.assertEqual(note.absolute_url(), 'http://cubicweb2.com/note/1234')
def test_absolute_url_empty_field(self):
req = self.request()
card = req.create_entity('Card', wikiid=u'', title=u'test')
- self.assertEquals(card.absolute_url(),
+ self.assertEqual(card.absolute_url(),
'http://testing.fr/cubicweb/card/eid/%s' % card.eid)
def test_create_entity(self):
@@ -535,10 +535,10 @@
p = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien',
connait=p1, evaluee=[p1, p2],
reverse_ecrit_par=note)
- self.assertEquals(p.nom, 'di mascio')
- self.assertEquals([c.nom for c in p.connait], ['fayolle'])
- self.assertEquals(sorted([c.nom for c in p.evaluee]), ['campeas', 'fayolle'])
- self.assertEquals([c.type for c in p.reverse_ecrit_par], ['z'])
+ self.assertEqual(p.nom, 'di mascio')
+ self.assertEqual([c.nom for c in p.connait], ['fayolle'])
+ self.assertEqual(sorted([c.nom for c in p.evaluee]), ['campeas', 'fayolle'])
+ self.assertEqual([c.type for c in p.reverse_ecrit_par], ['z'])
--- a/test/unittest_mail.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_mail.py Wed Sep 29 16:16:32 2010 +0200
@@ -51,7 +51,7 @@
mail = format_mail({'name': 'oim', 'email': 'oim@logilab.fr'},
['test@logilab.fr'], u'un petit cöucou', u'bïjour',
config=self.config)
- self.assertLinesEquals(mail.as_string(), """\
+ self.assertMultiLineEqual(mail.as_string(), """\
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
@@ -64,17 +64,17 @@
dW4gcGV0aXQgY8O2dWNvdQ==
""")
msg = message_from_string(mail.as_string())
- self.assertEquals(msg.get('subject'), u'bïjour')
- self.assertEquals(msg.get('from'), u'oim <oim@logilab.fr>')
- self.assertEquals(msg.get('to'), u'test@logilab.fr')
- self.assertEquals(msg.get('reply-to'), u'oim <oim@logilab.fr>, BimBam <bim@boum.fr>')
- self.assertEquals(msg.get_payload(decode=True), u'un petit cöucou')
+ self.assertEqual(msg.get('subject'), u'bïjour')
+ self.assertEqual(msg.get('from'), u'oim <oim@logilab.fr>')
+ self.assertEqual(msg.get('to'), u'test@logilab.fr')
+ self.assertEqual(msg.get('reply-to'), u'oim <oim@logilab.fr>, BimBam <bim@boum.fr>')
+ self.assertEqual(msg.get_payload(decode=True), u'un petit cöucou')
def test_format_mail_euro(self):
mail = format_mail({'name': u'oîm', 'email': u'oim@logilab.fr'},
['test@logilab.fr'], u'un petit cöucou €', u'bïjour €')
- self.assertLinesEquals(mail.as_string(), """\
+ self.assertMultiLineEqual(mail.as_string(), """\
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
@@ -86,11 +86,11 @@
dW4gcGV0aXQgY8O2dWNvdSDigqw=
""")
msg = message_from_string(mail.as_string())
- self.assertEquals(msg.get('subject'), u'bïjour €')
- self.assertEquals(msg.get('from'), u'oîm <oim@logilab.fr>')
- self.assertEquals(msg.get('to'), u'test@logilab.fr')
- self.assertEquals(msg.get('reply-to'), u'oîm <oim@logilab.fr>')
- self.assertEquals(msg.get_payload(decode=True), u'un petit cöucou €')
+ self.assertEqual(msg.get('subject'), u'bïjour €')
+ self.assertEqual(msg.get('from'), u'oîm <oim@logilab.fr>')
+ self.assertEqual(msg.get('to'), u'test@logilab.fr')
+ self.assertEqual(msg.get('reply-to'), u'oîm <oim@logilab.fr>')
+ self.assertEqual(msg.get_payload(decode=True), u'un petit cöucou €')
def test_format_mail_from_reply_to(self):
@@ -100,19 +100,19 @@
msg = format_mail({'name': u'', 'email': u''},
['test@logilab.fr'], u'un petit cöucou €', u'bïjour €',
config=self.config)
- self.assertEquals(msg.get('from'), u'')
- self.assertEquals(msg.get('reply-to'), None)
+ self.assertEqual(msg.get('from'), u'')
+ self.assertEqual(msg.get('reply-to'), None)
msg = format_mail({'name': u'tutu', 'email': u'tutu@logilab.fr'},
['test@logilab.fr'], u'un petit cöucou €', u'bïjour €',
config=self.config)
msg = message_from_string(msg.as_string())
- self.assertEquals(msg.get('from'), u'tutu <tutu@logilab.fr>')
- self.assertEquals(msg.get('reply-to'), u'tutu <tutu@logilab.fr>')
+ self.assertEqual(msg.get('from'), u'tutu <tutu@logilab.fr>')
+ self.assertEqual(msg.get('reply-to'), u'tutu <tutu@logilab.fr>')
msg = format_mail({'name': u'tutu', 'email': u'tutu@logilab.fr'},
['test@logilab.fr'], u'un petit cöucou €', u'bïjour €')
msg = message_from_string(msg.as_string())
- self.assertEquals(msg.get('from'), u'tutu <tutu@logilab.fr>')
- self.assertEquals(msg.get('reply-to'), u'tutu <tutu@logilab.fr>')
+ self.assertEqual(msg.get('from'), u'tutu <tutu@logilab.fr>')
+ self.assertEqual(msg.get('reply-to'), u'tutu <tutu@logilab.fr>')
# set sender name and address as expected
self.set_option('sender-name', 'cubicweb-test')
self.set_option('sender-addr', 'cubicweb-test@logilab.fr')
@@ -121,22 +121,22 @@
['test@logilab.fr'], u'un petit cöucou €', u'bïjour €',
config=self.config)
msg = message_from_string(msg.as_string())
- self.assertEquals(msg.get('from'), u'cubicweb-test <cubicweb-test@logilab.fr>')
- self.assertEquals(msg.get('reply-to'), u'cubicweb-test <cubicweb-test@logilab.fr>')
+ self.assertEqual(msg.get('from'), u'cubicweb-test <cubicweb-test@logilab.fr>')
+ self.assertEqual(msg.get('reply-to'), u'cubicweb-test <cubicweb-test@logilab.fr>')
# anonymous notification: only email specified
msg = format_mail({'email': u'tutu@logilab.fr'},
['test@logilab.fr'], u'un petit cöucou €', u'bïjour €',
config=self.config)
msg = message_from_string(msg.as_string())
- self.assertEquals(msg.get('from'), u'cubicweb-test <tutu@logilab.fr>')
- self.assertEquals(msg.get('reply-to'), u'cubicweb-test <tutu@logilab.fr>, cubicweb-test <cubicweb-test@logilab.fr>')
+ self.assertEqual(msg.get('from'), u'cubicweb-test <tutu@logilab.fr>')
+ self.assertEqual(msg.get('reply-to'), u'cubicweb-test <tutu@logilab.fr>, cubicweb-test <cubicweb-test@logilab.fr>')
# anonymous notification: only name specified
msg = format_mail({'name': u'tutu'},
['test@logilab.fr'], u'un petit cöucou €', u'bïjour €',
config=self.config)
msg = message_from_string(msg.as_string())
- self.assertEquals(msg.get('from'), u'tutu <cubicweb-test@logilab.fr>')
- self.assertEquals(msg.get('reply-to'), u'tutu <cubicweb-test@logilab.fr>')
+ self.assertEqual(msg.get('from'), u'tutu <cubicweb-test@logilab.fr>')
+ self.assertEqual(msg.get('reply-to'), u'tutu <cubicweb-test@logilab.fr>')
--- a/test/unittest_migration.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_migration.py Wed Sep 29 16:16:32 2010 +0200
@@ -52,26 +52,26 @@
self.config.__class__.cube_appobject_path = frozenset()
def test_filter_scripts_base(self):
- self.assertListEquals(filter_scripts(self.config, SMIGRDIR, (2,3,0), (2,4,0)),
+ self.assertListEqual(filter_scripts(self.config, SMIGRDIR, (2,3,0), (2,4,0)),
[])
- self.assertListEquals(filter_scripts(self.config, SMIGRDIR, (2,4,0), (2,5,0)),
+ self.assertListEqual(filter_scripts(self.config, SMIGRDIR, (2,4,0), (2,5,0)),
[((2, 5, 0), SMIGRDIR+'2.5.0_Any.sql')])
- self.assertListEquals(filter_scripts(self.config, SMIGRDIR, (2,5,0), (2,6,0)),
+ self.assertListEqual(filter_scripts(self.config, SMIGRDIR, (2,5,0), (2,6,0)),
[((2, 6, 0), SMIGRDIR+'2.6.0_Any.sql')])
- self.assertListEquals(filter_scripts(self.config, SMIGRDIR, (2,4,0), (2,6,0)),
+ self.assertListEqual(filter_scripts(self.config, SMIGRDIR, (2,4,0), (2,6,0)),
[((2, 5, 0), SMIGRDIR+'2.5.0_Any.sql'),
((2, 6, 0), SMIGRDIR+'2.6.0_Any.sql')])
- self.assertListEquals(filter_scripts(self.config, SMIGRDIR, (2,5,0), (2,5,1)),
+ self.assertListEqual(filter_scripts(self.config, SMIGRDIR, (2,5,0), (2,5,1)),
[])
- self.assertListEquals(filter_scripts(self.config, SMIGRDIR, (2,5,0), (2,10,2)),
+ self.assertListEqual(filter_scripts(self.config, SMIGRDIR, (2,5,0), (2,10,2)),
[((2, 6, 0), SMIGRDIR+'2.6.0_Any.sql'),
((2, 10, 2), SMIGRDIR+'2.10.2_Any.sql')])
- self.assertListEquals(filter_scripts(self.config, SMIGRDIR, (2,5,1), (2,6,0)),
+ self.assertListEqual(filter_scripts(self.config, SMIGRDIR, (2,5,1), (2,6,0)),
[((2, 6, 0), SMIGRDIR+'2.6.0_Any.sql')])
- self.assertListEquals(filter_scripts(self.config, TMIGRDIR, (0,0,2), (0,0,3)),
+ self.assertListEqual(filter_scripts(self.config, TMIGRDIR, (0,0,2), (0,0,3)),
[((0, 0, 3), TMIGRDIR+'0.0.3_Any.py')])
- self.assertListEquals(filter_scripts(self.config, TMIGRDIR, (0,0,2), (0,0,4)),
+ self.assertListEqual(filter_scripts(self.config, TMIGRDIR, (0,0,2), (0,0,4)),
[((0, 0, 3), TMIGRDIR+'0.0.3_Any.py'),
((0, 0, 4), TMIGRDIR+'0.0.4_Any.py')])
@@ -82,16 +82,16 @@
self.assertIsInstance(config.migration_handler(), MigrationHelper)
config = self.config
config.__class__.name = 'twisted'
- self.assertListEquals(filter_scripts(config, TMIGRDIR, (0,0,4), (0,1,0)),
+ self.assertListEqual(filter_scripts(config, TMIGRDIR, (0,0,4), (0,1,0)),
[((0, 1 ,0), TMIGRDIR+'0.1.0_common.py'),
((0, 1 ,0), TMIGRDIR+'0.1.0_web.py')])
config.__class__.name = 'repository'
- self.assertListEquals(filter_scripts(config, TMIGRDIR, (0,0,4), (0,1,0)),
+ self.assertListEqual(filter_scripts(config, TMIGRDIR, (0,0,4), (0,1,0)),
[((0, 1 ,0), TMIGRDIR+'0.1.0_Any.py'),
((0, 1 ,0), TMIGRDIR+'0.1.0_common.py'),
((0, 1 ,0), TMIGRDIR+'0.1.0_repository.py')])
config.__class__.name = 'all-in-one'
- self.assertListEquals(filter_scripts(config, TMIGRDIR, (0,0,4), (0,1,0)),
+ self.assertListEqual(filter_scripts(config, TMIGRDIR, (0,0,4), (0,1,0)),
[((0, 1 ,0), TMIGRDIR+'0.1.0_Any.py'),
((0, 1 ,0), TMIGRDIR+'0.1.0_common.py'),
((0, 1 ,0), TMIGRDIR+'0.1.0_repository.py'),
@@ -107,7 +107,7 @@
"""make sure database can be created"""
config = ApptestConfiguration('data')
source = config.sources()['system']
- self.assertEquals(source['db-driver'], 'sqlite')
+ self.assertEqual(source['db-driver'], 'sqlite')
cleanup_sqlite(source['db-name'], removetemplate=True)
init_test_database(config=config)
--- a/test/unittest_req.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_req.py Wed Sep 29 16:16:32 2010 +0200
@@ -23,11 +23,11 @@
class RebuildURLTC(TestCase):
def test_rebuild_url(self):
rebuild_url = RequestSessionBase(None).rebuild_url
- self.assertEquals(rebuild_url('http://logilab.fr?__message=pouet', __message='hop'),
+ self.assertEqual(rebuild_url('http://logilab.fr?__message=pouet', __message='hop'),
'http://logilab.fr?__message=hop')
- self.assertEquals(rebuild_url('http://logilab.fr', __message='hop'),
+ self.assertEqual(rebuild_url('http://logilab.fr', __message='hop'),
'http://logilab.fr?__message=hop')
- self.assertEquals(rebuild_url('http://logilab.fr?vid=index', __message='hop'),
+ self.assertEqual(rebuild_url('http://logilab.fr?vid=index', __message='hop'),
'http://logilab.fr?__message=hop&vid=index')
def test_build_url(self):
--- a/test/unittest_rqlrewrite.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_rqlrewrite.py Wed Sep 29 16:16:32 2010 +0200
@@ -15,9 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-"""
from logilab.common.testlib import unittest_main, TestCase
from logilab.common.testlib import mock_object
from yams import BadSchemaDefinition
@@ -109,7 +107,7 @@
rqlst = parse('Any S WHERE S documented_by C, C eid %(u)s')
rewrite(rqlst, {('C', 'X'): (card_constraint,), ('S', 'X'): affaire_constraints},
kwargs)
- self.assertTextEquals(rqlst.as_string(),
+ self.assertMultiLineEqual(rqlst.as_string(),
"Any S WHERE S documented_by C, C eid %(u)s, B eid %(D)s, "
"EXISTS(C in_state A, B in_group E, F require_state A, "
"F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission), "
@@ -272,7 +270,7 @@
"EXISTS(U in_group B, B name 'managers', B is CWGroup), T is TrInfo")
def test_unsupported_constraint_3(self):
- self.skip('raise unauthorized for now')
+ self.skipTest('raise unauthorized for now')
trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"')
rqlst = parse('Any T WHERE T wf_info_for X')
rewrite(rqlst, {('T', 'X'): (trinfo_constraint, 'X in_group G, G name "managers"')}, {})
--- a/test/unittest_rset.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_rset.py Wed Sep 29 16:16:32 2010 +0200
@@ -16,9 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""unit tests for module cubicweb.utils
-
-"""
+"""unit tests for module cubicweb.utils"""
from urlparse import urlsplit
import pickle
@@ -52,7 +50,7 @@
}
for rql, relations in queries.items():
result = list(attr_desc_iterator(parse(rql).children[0]))
- self.assertEquals((rql, result), (rql, relations))
+ self.assertEqual((rql, result), (rql, relations))
def test_relations_description_indexed(self):
"""tests relations_description() function"""
@@ -63,7 +61,7 @@
for rql, results in queries.items():
for var_index, relations in results.items():
result = list(attr_desc_iterator(parse(rql).children[0], var_index))
- self.assertEquals(result, relations)
+ self.assertEqual(result, relations)
@@ -79,15 +77,15 @@
def compare_urls(self, url1, url2):
info1 = urlsplit(url1)
info2 = urlsplit(url2)
- self.assertEquals(info1[:3], info2[:3])
+ self.assertEqual(info1[:3], info2[:3])
if info1[3] != info2[3]:
params1 = dict(pair.split('=') for pair in info1[3].split('&'))
params2 = dict(pair.split('=') for pair in info1[3].split('&'))
- self.assertDictEquals(params1, params2)
+ self.assertDictEqual(params1, params2)
def test_pickle(self):
del self.rset.req
- self.assertEquals(len(pickle.dumps(self.rset)), 392)
+ self.assertEqual(len(pickle.dumps(self.rset)), 392)
def test_build_url(self):
req = self.request()
@@ -105,9 +103,9 @@
def test_resultset_build(self):
"""test basic build of a ResultSet"""
rs = ResultSet([1,2,3], 'CWGroup X', description=['CWGroup', 'CWGroup', 'CWGroup'])
- self.assertEquals(rs.rowcount, 3)
- self.assertEquals(rs.rows, [1,2,3])
- self.assertEquals(rs.description, ['CWGroup', 'CWGroup', 'CWGroup'])
+ self.assertEqual(rs.rowcount, 3)
+ self.assertEqual(rs.rows, [1,2,3])
+ self.assertEqual(rs.description, ['CWGroup', 'CWGroup', 'CWGroup'])
def test_resultset_limit(self):
@@ -117,12 +115,12 @@
rs.req = self.request()
rs.vreg = self.vreg
- self.assertEquals(rs.limit(2).rows, [[12000, 'adim'], [13000, 'syt']])
+ self.assertEqual(rs.limit(2).rows, [[12000, 'adim'], [13000, 'syt']])
rs2 = rs.limit(2, offset=1)
- self.assertEquals(rs2.rows, [[13000, 'syt'], [14000, 'nico']])
- self.assertEquals(rs2.get_entity(0, 0).cw_row, 0)
- self.assertEquals(rs.limit(2, offset=2).rows, [[14000, 'nico']])
- self.assertEquals(rs.limit(2, offset=3).rows, [])
+ self.assertEqual(rs2.rows, [[13000, 'syt'], [14000, 'nico']])
+ self.assertEqual(rs2.get_entity(0, 0).cw_row, 0)
+ self.assertEqual(rs.limit(2, offset=2).rows, [[14000, 'nico']])
+ self.assertEqual(rs.limit(2, offset=3).rows, [])
def test_resultset_filter(self):
@@ -135,8 +133,8 @@
return entity.login != 'nico'
rs2 = rs.filtered_rset(test_filter)
- self.assertEquals(len(rs2), 2)
- self.assertEquals([login for _, login in rs2], ['adim', 'syt'])
+ self.assertEqual(len(rs2), 2)
+ self.assertEqual([login for _, login in rs2], ['adim', 'syt'])
def test_resultset_transform(self):
rs = ResultSet([[12, 'adim'], [13, 'syt'], [14, 'nico']],
@@ -147,8 +145,8 @@
return row[1:], desc[1:]
rs2 = rs.transformed_rset(test_transform)
- self.assertEquals(len(rs2), 3)
- self.assertEquals(list(rs2), [['adim'],['syt'],['nico']])
+ self.assertEqual(len(rs2), 3)
+ self.assertEqual(list(rs2), [['adim'],['syt'],['nico']])
def test_resultset_sort(self):
rs = ResultSet([[12000, 'adim'], [13000, 'syt'], [14000, 'nico']],
@@ -157,23 +155,35 @@
rs.req = self.request()
rs.vreg = self.vreg
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
rs2 = rs.sorted_rset(lambda e:e.cw_attr_cache['login'])
self.assertEquals(len(rs2), 3)
self.assertEquals([login for _, login in rs2], ['adim', 'nico', 'syt'])
+=======
+ rs2 = rs.sorted_rset(lambda e:e['login'])
+ self.assertEqual(len(rs2), 3)
+ self.assertEqual([login for _, login in rs2], ['adim', 'nico', 'syt'])
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
# make sure rs is unchanged
- self.assertEquals([login for _, login in rs], ['adim', 'syt', 'nico'])
+ self.assertEqual([login for _, login in rs], ['adim', 'syt', 'nico'])
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
rs2 = rs.sorted_rset(lambda e:e.cw_attr_cache['login'], reverse=True)
self.assertEquals(len(rs2), 3)
self.assertEquals([login for _, login in rs2], ['syt', 'nico', 'adim'])
+=======
+ rs2 = rs.sorted_rset(lambda e:e['login'], reverse=True)
+ self.assertEqual(len(rs2), 3)
+ self.assertEqual([login for _, login in rs2], ['syt', 'nico', 'adim'])
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
# make sure rs is unchanged
- self.assertEquals([login for _, login in rs], ['adim', 'syt', 'nico'])
+ self.assertEqual([login for _, login in rs], ['adim', 'syt', 'nico'])
rs3 = rs.sorted_rset(lambda row: row[1], col=-1)
- self.assertEquals(len(rs3), 3)
- self.assertEquals([login for _, login in rs3], ['adim', 'nico', 'syt'])
+ self.assertEqual(len(rs3), 3)
+ self.assertEqual([login for _, login in rs3], ['adim', 'nico', 'syt'])
# make sure rs is unchanged
- self.assertEquals([login for _, login in rs], ['adim', 'syt', 'nico'])
+ self.assertEqual([login for _, login in rs], ['adim', 'syt', 'nico'])
def test_resultset_split(self):
rs = ResultSet([[12000, 'adim', u'Adim chez les pinguins'],
@@ -187,33 +197,49 @@
rs.req = self.request()
rs.vreg = self.vreg
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
rsets = rs.split_rset(lambda e:e.cw_attr_cache['login'])
self.assertEquals(len(rsets), 3)
self.assertEquals([login for _, login,_ in rsets[0]], ['adim', 'adim'])
self.assertEquals([login for _, login,_ in rsets[1]], ['syt'])
self.assertEquals([login for _, login,_ in rsets[2]], ['nico', 'nico'])
+=======
+ rsets = rs.split_rset(lambda e:e['login'])
+ self.assertEqual(len(rsets), 3)
+ self.assertEqual([login for _, login,_ in rsets[0]], ['adim', 'adim'])
+ self.assertEqual([login for _, login,_ in rsets[1]], ['syt'])
+ self.assertEqual([login for _, login,_ in rsets[2]], ['nico', 'nico'])
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
# make sure rs is unchanged
- self.assertEquals([login for _, login,_ in rs], ['adim', 'adim', 'syt', 'nico', 'nico'])
+ self.assertEqual([login for _, login,_ in rs], ['adim', 'adim', 'syt', 'nico', 'nico'])
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
rsets = rs.split_rset(lambda e:e.cw_attr_cache['login'], return_dict=True)
self.assertEquals(len(rsets), 3)
self.assertEquals([login for _, login,_ in rsets['nico']], ['nico', 'nico'])
self.assertEquals([login for _, login,_ in rsets['adim']], ['adim', 'adim'])
self.assertEquals([login for _, login,_ in rsets['syt']], ['syt'])
+=======
+ rsets = rs.split_rset(lambda e:e['login'], return_dict=True)
+ self.assertEqual(len(rsets), 3)
+ self.assertEqual([login for _, login,_ in rsets['nico']], ['nico', 'nico'])
+ self.assertEqual([login for _, login,_ in rsets['adim']], ['adim', 'adim'])
+ self.assertEqual([login for _, login,_ in rsets['syt']], ['syt'])
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
# make sure rs is unchanged
- self.assertEquals([login for _, login,_ in rs], ['adim', 'adim', 'syt', 'nico', 'nico'])
+ self.assertEqual([login for _, login,_ in rs], ['adim', 'adim', 'syt', 'nico', 'nico'])
rsets = rs.split_rset(lambda s: s.count('d'), col=2)
- self.assertEquals(len(rsets), 2)
- self.assertEquals([title for _, _, title in rsets[0]],
+ self.assertEqual(len(rsets), 2)
+ self.assertEqual([title for _, _, title in rsets[0]],
[u"Adim chez les pinguins",
u"Jardiner facile",
u"L'épluchage du castor commun",])
- self.assertEquals([title for _, _, title in rsets[1]],
+ self.assertEqual([title for _, _, title in rsets[1]],
[u"Le carrelage en 42 leçons",
u"La tarte tatin en 15 minutes",])
# make sure rs is unchanged
- self.assertEquals([title for _, _, title in rs],
+ self.assertEqual([title for _, _, title in rs],
[u'Adim chez les pinguins',
u'Jardiner facile',
u'Le carrelage en 42 leçons',
@@ -228,15 +254,27 @@
def test_get_entity_simple(self):
self.request().create_entity('CWUser', login=u'adim', upassword='adim',
- surname=u'di mascio', firstname=u'adrien')
+ surname=u'di mascio', firstname=u'adrien')
e = self.execute('Any X,T WHERE X login "adim", X surname T').get_entity(0, 0)
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
self.assertEquals(e.cw_attr_cache['surname'], 'di mascio')
self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'firstname')
self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'creation_date')
self.assertEquals(pprelcachedict(e._cw_related_cache), [])
+=======
+ self.assertEqual(e['surname'], 'di mascio')
+ self.assertRaises(KeyError, e.__getitem__, 'firstname')
+ self.assertRaises(KeyError, e.__getitem__, 'creation_date')
+ self.assertEqual(pprelcachedict(e._cw_related_cache), [])
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
e.complete()
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
self.assertEquals(e.cw_attr_cache['firstname'], 'adrien')
self.assertEquals(pprelcachedict(e._cw_related_cache), [])
+=======
+ self.assertEqual(e['firstname'], 'adrien')
+ self.assertEqual(pprelcachedict(e._cw_related_cache), [])
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
def test_get_entity_advanced(self):
self.request().create_entity('Bookmark', title=u'zou', path=u'/view')
@@ -244,24 +282,47 @@
rset = self.execute('Any X,Y,XT,YN WHERE X bookmarked_by Y, X title XT, Y login YN')
e = rset.get_entity(0, 0)
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
self.assertEquals(e.cw_row, 0)
self.assertEquals(e.cw_col, 0)
self.assertEquals(e.cw_attr_cache['title'], 'zou')
self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'path')
self.assertEquals(e.view('text'), 'zou')
self.assertEquals(pprelcachedict(e._cw_related_cache), [])
+=======
+ self.assertEqual(e.cw_row, 0)
+ self.assertEqual(e.cw_col, 0)
+ self.assertEqual(e['title'], 'zou')
+ self.assertRaises(KeyError, e.__getitem__, 'path')
+ self.assertEqual(e.view('text'), 'zou')
+ self.assertEqual(pprelcachedict(e._cw_related_cache), [])
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
e = rset.get_entity(0, 1)
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
self.assertEquals(e.cw_row, 0)
self.assertEquals(e.cw_col, 1)
self.assertEquals(e.cw_attr_cache['login'], 'anon')
self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'firstname')
self.assertEquals(pprelcachedict(e._cw_related_cache),
+=======
+ self.assertEqual(e.cw_row, 0)
+ self.assertEqual(e.cw_col, 1)
+ self.assertEqual(e['login'], 'anon')
+ self.assertRaises(KeyError, e.__getitem__, 'firstname')
+ self.assertEqual(pprelcachedict(e._cw_related_cache),
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
[])
e.complete()
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
self.assertEquals(e.cw_attr_cache['firstname'], None)
self.assertEquals(e.view('text'), 'anon')
self.assertEquals(pprelcachedict(e._cw_related_cache),
+=======
+ self.assertEqual(e['firstname'], None)
+ self.assertEqual(e.view('text'), 'anon')
+ self.assertEqual(pprelcachedict(e._cw_related_cache),
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
[])
self.assertRaises(NotAnEntity, rset.get_entity, 0, 2)
@@ -273,7 +334,7 @@
seid = self.execute('State X WHERE X name "activated"')[0][0]
# for_user / in_group are prefetched in CWUser __init__, in_state should
# be filed from our query rset
- self.assertEquals(pprelcachedict(e._cw_related_cache),
+ self.assertEqual(pprelcachedict(e._cw_related_cache),
[('in_state_subject', [seid])])
def test_get_entity_advanced_prefilled_cache(self):
@@ -282,17 +343,32 @@
rset = self.execute('Any X,U,S,XT,UL,SN WHERE X created_by U, U in_state S, '
'X title XT, S name SN, U login UL, X eid %s' % e.eid)
e = rset.get_entity(0, 0)
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
self.assertEquals(e.cw_attr_cache['title'], 'zou')
self.assertEquals(pprelcachedict(e._cw_related_cache),
+=======
+ self.assertEqual(e['title'], 'zou')
+ self.assertEqual(pprelcachedict(e._cw_related_cache),
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
[('created_by_subject', [5])])
# first level of recursion
u = e.created_by[0]
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
self.assertEquals(u.cw_attr_cache['login'], 'admin')
self.assertRaises(KeyError, u.cw_attr_cache.__getitem__, 'firstname')
+=======
+ self.assertEqual(u['login'], 'admin')
+ self.assertRaises(KeyError, u.__getitem__, 'firstname')
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
# second level of recursion
s = u.in_state[0]
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
self.assertEquals(s.cw_attr_cache['name'], 'activated')
self.assertRaises(KeyError, s.cw_attr_cache.__getitem__, 'description')
+=======
+ self.assertEqual(s['name'], 'activated')
+ self.assertRaises(KeyError, s.__getitem__, 'description')
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
def test_get_entity_cache_with_left_outer_join(self):
@@ -302,11 +378,11 @@
e = rset.get_entity(0, 0)
# if any of the assertion below fails with a KeyError, the relation is not cached
# related entities should be an empty list
- self.assertEquals(e._cw_relation_cache('primary_email', 'subject', True), ())
+ self.assertEqual(e._cw_relation_cache('primary_email', 'subject', True), ())
# related rset should be an empty rset
cached = e._cw_relation_cache('primary_email', 'subject', False)
self.assertIsInstance(cached, ResultSet)
- self.assertEquals(cached.rowcount, 0)
+ self.assertEqual(cached.rowcount, 0)
def test_get_entity_union(self):
@@ -320,16 +396,20 @@
('CWGroup', 'users'))
for entity in rset.entities(): # test get_entity for each row actually
etype, n = expected[entity.cw_row]
- self.assertEquals(entity.__regid__, etype)
+ self.assertEqual(entity.__regid__, etype)
attr = etype == 'Bookmark' and 'title' or 'name'
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/test/unittest_rset.py
self.assertEquals(entity.cw_attr_cache[attr], n)
+=======
+ self.assertEqual(entity[attr], n)
+>>>>>>> /tmp/unittest_rset.py~other.4ZXPmp
def test_related_entity_optional(self):
e = self.request().create_entity('Bookmark', title=u'aaaa', path=u'path')
rset = self.execute('Any B,U,L WHERE B bookmarked_by U?, U login L')
entity, rtype = rset.related_entity(0, 2)
- self.assertEquals(entity, None)
- self.assertEquals(rtype, None)
+ self.assertEqual(entity, None)
+ self.assertEqual(rtype, None)
def test_related_entity_union_subquery(self):
e = self.request().create_entity('Bookmark', title=u'aaaa', path=u'path')
@@ -338,27 +418,27 @@
' UNION '
' (Any X,N WHERE X is Bookmark, X title N))')
entity, rtype = rset.related_entity(0, 1)
- self.assertEquals(entity.eid, e.eid)
- self.assertEquals(rtype, 'title')
+ self.assertEqual(entity.eid, e.eid)
+ self.assertEqual(rtype, 'title')
entity, rtype = rset.related_entity(1, 1)
- self.assertEquals(entity.__regid__, 'CWGroup')
- self.assertEquals(rtype, 'name')
+ self.assertEqual(entity.__regid__, 'CWGroup')
+ self.assertEqual(rtype, 'name')
#
rset = self.execute('Any X,N ORDERBY N WHERE X is Bookmark WITH X,N BEING '
'((Any X,N WHERE X is CWGroup, X name N)'
' UNION '
' (Any X,N WHERE X is Bookmark, X title N))')
entity, rtype = rset.related_entity(0, 1)
- self.assertEquals(entity.eid, e.eid)
- self.assertEquals(rtype, 'title')
+ self.assertEqual(entity.eid, e.eid)
+ self.assertEqual(rtype, 'title')
#
rset = self.execute('Any X,N ORDERBY N WITH N,X BEING '
'((Any N,X WHERE X is CWGroup, X name N)'
' UNION '
' (Any N,X WHERE X is Bookmark, X title N))')
entity, rtype = rset.related_entity(0, 1)
- self.assertEquals(entity.eid, e.eid)
- self.assertEquals(rtype, 'title')
+ self.assertEqual(entity.eid, e.eid)
+ self.assertEqual(rtype, 'title')
def test_related_entity_trap_subquery(self):
req = self.request()
@@ -372,7 +452,7 @@
rset = self.execute('Any X,S,L WHERE X in_state S '
'WITH X, L BEING (Any X,MAX(L) GROUPBY X '
'WHERE X is CWUser, T? wf_info_for X, T creation_date L)')
- self.assertEquals(len(rset), 2)
+ self.assertEqual(len(rset), 2)
rset.related_entity(0, 1)
rset.related_entity(0, 2)
@@ -380,28 +460,28 @@
rset = self.execute('Any U,G WHERE U in_group G')
# make sure we have at least one element
self.failUnless(rset)
- self.assertEquals(set(e.e_schema.type for e in rset.entities(0)),
+ self.assertEqual(set(e.e_schema.type for e in rset.entities(0)),
set(['CWUser',]))
- self.assertEquals(set(e.e_schema.type for e in rset.entities(1)),
+ self.assertEqual(set(e.e_schema.type for e in rset.entities(1)),
set(['CWGroup',]))
def test_printable_rql(self):
rset = self.execute(u'CWEType X WHERE X final FALSE')
- self.assertEquals(rset.printable_rql(),
+ self.assertEqual(rset.printable_rql(),
'Any X WHERE X final FALSE, X is CWEType')
def test_searched_text(self):
rset = self.execute(u'Any X WHERE X has_text "foobar"')
- self.assertEquals(rset.searched_text(), 'foobar')
+ self.assertEqual(rset.searched_text(), 'foobar')
rset = self.execute(u'Any X WHERE X has_text %(text)s', {'text' : 'foo'})
- self.assertEquals(rset.searched_text(), 'foo')
+ self.assertEqual(rset.searched_text(), 'foo')
def test_union_limited_rql(self):
rset = self.execute('(Any X,N WHERE X is Bookmark, X title N)'
' UNION '
'(Any X,N WHERE X is CWGroup, X name N)')
rset.limit(2, 10, inplace=True)
- self.assertEquals(rset.limited_rql(),
+ self.assertEqual(rset.limited_rql(),
'Any A,B LIMIT 2 OFFSET 10 '
'WITH A,B BEING ('
'(Any X,N WHERE X is Bookmark, X title N) '
@@ -411,12 +491,12 @@
def test_count_users_by_date(self):
rset = self.execute('Any D, COUNT(U) GROUPBY D WHERE U is CWUser, U creation_date D')
- self.assertEquals(rset.related_entity(0,0), (None, None))
+ self.assertEqual(rset.related_entity(0,0), (None, None))
def test_str(self):
rset = self.execute('(Any X,N WHERE X is CWGroup, X name N)')
self.assertIsInstance(str(rset), basestring)
- self.assertEquals(len(str(rset).splitlines()), 1)
+ self.assertEqual(len(str(rset).splitlines()), 1)
def test_repr(self):
rset = self.execute('(Any X,N WHERE X is CWGroup, X name N)')
@@ -425,7 +505,7 @@
rset = self.execute('(Any X WHERE X is CWGroup, X name "managers")')
self.assertIsInstance(str(rset), basestring)
- self.assertEquals(len(str(rset).splitlines()), 1)
+ self.assertEqual(len(str(rset).splitlines()), 1)
if __name__ == '__main__':
unittest_main()
--- a/test/unittest_rtags.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_rtags.py Wed Sep 29 16:16:32 2010 +0200
@@ -28,25 +28,25 @@
rtags.tag_subject_of(('Societe', 'travaille', '*'), 'primary')
rtags.tag_subject_of(('*', 'evaluee', '*'), 'secondary')
rtags.tag_object_of(('*', 'tags', '*'), 'generated')
- self.assertEquals(rtags.get('Note', 'evaluee', '*', 'subject'),
+ self.assertEqual(rtags.get('Note', 'evaluee', '*', 'subject'),
'secondary')
- self.assertEquals(rtags.get('Societe', 'travaille', '*', 'subject'),
+ self.assertEqual(rtags.get('Societe', 'travaille', '*', 'subject'),
'primary')
- self.assertEquals(rtags.get('Note', 'travaille', '*', 'subject'),
+ self.assertEqual(rtags.get('Note', 'travaille', '*', 'subject'),
None)
- self.assertEquals(rtags.get('Note', 'tags', '*', 'subject'),
+ self.assertEqual(rtags.get('Note', 'tags', '*', 'subject'),
None)
- self.assertEquals(rtags.get('*', 'tags', 'Note', 'object'),
+ self.assertEqual(rtags.get('*', 'tags', 'Note', 'object'),
'generated')
- self.assertEquals(rtags.get('Tag', 'tags', '*', 'object'),
+ self.assertEqual(rtags.get('Tag', 'tags', '*', 'object'),
'generated')
-# self.assertEquals(rtags.rtag('evaluee', 'Note', 'subject'), set(('secondary', 'link')))
-# self.assertEquals(rtags.is_inlined('evaluee', 'Note', 'subject'), False)
-# self.assertEquals(rtags.rtag('evaluee', 'Personne', 'subject'), set(('secondary', 'link')))
-# self.assertEquals(rtags.is_inlined('evaluee', 'Personne', 'subject'), False)
-# self.assertEquals(rtags.rtag('ecrit_par', 'Note', 'object'), set(('inlineview', 'link')))
-# self.assertEquals(rtags.is_inlined('ecrit_par', 'Note', 'object'), True)
+# self.assertEqual(rtags.rtag('evaluee', 'Note', 'subject'), set(('secondary', 'link')))
+# self.assertEqual(rtags.is_inlined('evaluee', 'Note', 'subject'), False)
+# self.assertEqual(rtags.rtag('evaluee', 'Personne', 'subject'), set(('secondary', 'link')))
+# self.assertEqual(rtags.is_inlined('evaluee', 'Personne', 'subject'), False)
+# self.assertEqual(rtags.rtag('ecrit_par', 'Note', 'object'), set(('inlineview', 'link')))
+# self.assertEqual(rtags.is_inlined('ecrit_par', 'Note', 'object'), True)
# class Personne2(Personne):
# id = 'Personne'
# __rtags__ = {
@@ -54,21 +54,21 @@
# }
# self.vreg.register(Personne2)
# rtags = Personne2.rtags
-# self.assertEquals(rtags.rtag('evaluee', 'Note', 'subject'), set(('inlineview', 'link')))
-# self.assertEquals(rtags.is_inlined('evaluee', 'Note', 'subject'), True)
-# self.assertEquals(rtags.rtag('evaluee', 'Personne', 'subject'), set(('secondary', 'link')))
-# self.assertEquals(rtags.is_inlined('evaluee', 'Personne', 'subject'), False)
+# self.assertEqual(rtags.rtag('evaluee', 'Note', 'subject'), set(('inlineview', 'link')))
+# self.assertEqual(rtags.is_inlined('evaluee', 'Note', 'subject'), True)
+# self.assertEqual(rtags.rtag('evaluee', 'Personne', 'subject'), set(('secondary', 'link')))
+# self.assertEqual(rtags.is_inlined('evaluee', 'Personne', 'subject'), False)
def test_rtagset_expansion(self):
rtags = RelationTagsSet()
rtags.tag_subject_of(('Societe', 'travaille', '*'), 'primary')
rtags.tag_subject_of(('*', 'travaille', '*'), 'secondary')
- self.assertEquals(rtags.get('Societe', 'travaille', '*', 'subject'),
+ self.assertEqual(rtags.get('Societe', 'travaille', '*', 'subject'),
set(('primary', 'secondary')))
- self.assertEquals(rtags.get('Note', 'travaille', '*', 'subject'),
+ self.assertEqual(rtags.get('Note', 'travaille', '*', 'subject'),
set(('secondary',)))
- self.assertEquals(rtags.get('Note', 'tags', "*", 'subject'),
+ self.assertEqual(rtags.get('Note', 'tags', "*", 'subject'),
set())
def test_rtagdict_expansion(self):
@@ -79,16 +79,16 @@
{'key1': 'val0', 'key3': 'val0'})
rtags.tag_subject_of(('Societe', 'travaille', '*'),
{'key2': 'val2'})
- self.assertEquals(rtags.get('Societe', 'travaille', '*', 'subject'),
+ self.assertEqual(rtags.get('Societe', 'travaille', '*', 'subject'),
{'key1': 'val1', 'key2': 'val2', 'key3': 'val0'})
- self.assertEquals(rtags.get('Note', 'travaille', '*', 'subject'),
+ self.assertEqual(rtags.get('Note', 'travaille', '*', 'subject'),
{'key1': 'val0', 'key3': 'val0'})
- self.assertEquals(rtags.get('Note', 'tags', "*", 'subject'),
+ self.assertEqual(rtags.get('Note', 'tags', "*", 'subject'),
{})
rtags.setdefault(('Societe', 'travaille', '*', 'subject'), 'key1', 'val4')
rtags.setdefault(('Societe', 'travaille', '*', 'subject'), 'key4', 'val4')
- self.assertEquals(rtags.get('Societe', 'travaille', '*', 'subject'),
+ self.assertEqual(rtags.get('Societe', 'travaille', '*', 'subject'),
{'key1': 'val1', 'key2': 'val2', 'key3': 'val0', 'key4': 'val4'})
if __name__ == '__main__':
--- a/test/unittest_schema.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_schema.py Wed Sep 29 16:16:32 2010 +0200
@@ -142,13 +142,13 @@
def test_erqlexpression(self):
self.assertRaises(RQLSyntaxError, ERQLExpression, '1')
expr = ERQLExpression('X travaille S, S owned_by U')
- self.assertEquals(str(expr), 'Any X WHERE X travaille S, S owned_by U, X eid %(x)s, U eid %(u)s')
+ self.assertEqual(str(expr), 'Any X WHERE X travaille S, S owned_by U, X eid %(x)s, U eid %(u)s')
def test_rrqlexpression(self):
self.assertRaises(Exception, RRQLExpression, '1')
self.assertRaises(RQLSyntaxError, RRQLExpression, 'O X Y')
expr = RRQLExpression('U has_update_permission O')
- self.assertEquals(str(expr), 'Any O,U WHERE U has_update_permission O, O eid %(o)s, U eid %(u)s')
+ self.assertEqual(str(expr), 'Any O,U WHERE U has_update_permission O, O eid %(o)s, U eid %(u)s')
loader = CubicWebSchemaLoader()
config = TestConfiguration('data')
@@ -158,15 +158,15 @@
def test_order_eschemas(self):
schema = loader.load(config)
- self.assertEquals(order_eschemas([schema['Note'], schema['SubNote']]),
+ self.assertEqual(order_eschemas([schema['Note'], schema['SubNote']]),
[schema['Note'], schema['SubNote']])
- self.assertEquals(order_eschemas([schema['SubNote'], schema['Note']]),
+ self.assertEqual(order_eschemas([schema['SubNote'], schema['Note']]),
[schema['Note'], schema['SubNote']])
def test_knownValues_load_schema(self):
schema = loader.load(config)
self.assert_(isinstance(schema, CubicWebSchema))
- self.assertEquals(schema.name, 'data')
+ self.assertEqual(schema.name, 'data')
entities = [str(e) for e in schema.entities()]
entities.sort()
expected_entities = ['BaseTransition', 'Bookmark', 'Boolean', 'Bytes', 'Card',
@@ -181,7 +181,7 @@
'Societe', 'State', 'String', 'SubNote', 'SubWorkflowExitPoint',
'Tag', 'Time', 'Transition', 'TrInfo',
'Workflow', 'WorkflowTransition']
- self.assertListEquals(entities, sorted(expected_entities))
+ self.assertListEqual(entities, sorted(expected_entities))
relations = [str(r) for r in schema.relations()]
relations.sort()
expected_relations = ['add_permission', 'address', 'alias', 'allowed_transition',
@@ -227,11 +227,11 @@
'wf_info_for', 'wikiid', 'workflow_of']
- self.assertListEquals(relations, expected_relations)
+ self.assertListEqual(relations, expected_relations)
eschema = schema.eschema('CWUser')
rels = sorted(str(r) for r in eschema.subject_relations())
- self.assertListEquals(rels, ['created_by', 'creation_date', 'custom_workflow', 'cwuri', 'eid',
+ self.assertListEqual(rels, ['created_by', 'creation_date', 'custom_workflow', 'cwuri', 'eid',
'evaluee', 'firstname', 'has_text', 'identity',
'in_group', 'in_state', 'is',
'is_instance_of', 'last_login_time',
@@ -239,11 +239,11 @@
'primary_email', 'surname', 'upassword',
'use_email'])
rels = sorted(r.type for r in eschema.object_relations())
- self.assertListEquals(rels, ['bookmarked_by', 'created_by', 'for_user',
+ self.assertListEqual(rels, ['bookmarked_by', 'created_by', 'for_user',
'identity', 'owned_by', 'wf_info_for'])
rschema = schema.rschema('relation_type')
properties = rschema.rdef('CWAttribute', 'CWRType')
- self.assertEquals(properties.cardinality, '1*')
+ self.assertEqual(properties.cardinality, '1*')
constraints = properties.constraints
self.failUnlessEqual(len(constraints), 1, constraints)
constraint = constraints[0]
@@ -258,13 +258,13 @@
def test_permission_settings(self):
schema = loader.load(config)
aschema = schema['TrInfo'].rdef('comment')
- self.assertEquals(aschema.get_groups('read'),
+ self.assertEqual(aschema.get_groups('read'),
set(('managers', 'users', 'guests')))
- self.assertEquals(aschema.get_rqlexprs('read'),
+ self.assertEqual(aschema.get_rqlexprs('read'),
())
- self.assertEquals(aschema.get_groups('update'),
+ self.assertEqual(aschema.get_groups('update'),
set(('managers',)))
- self.assertEquals([x.expression for x in aschema.get_rqlexprs('update')],
+ self.assertEqual([x.expression for x in aschema.get_rqlexprs('update')],
['U has_update_permission X'])
class BadSchemaRQLExprTC(TestCase):
@@ -279,7 +279,7 @@
self.loader.handle_file(join(DATADIR, schemafile))
ex = self.assertRaises(BadSchemaDefinition,
self.loader._build_schema, 'toto', False)
- self.assertEquals(str(ex), msg)
+ self.assertEqual(str(ex), msg)
def test_rrqlexpr_on_etype(self):
self._test('rrqlexpr_on_eetype.py',
@@ -301,12 +301,12 @@
class NormalizeExpressionTC(TestCase):
def test(self):
- self.assertEquals(normalize_expression('X bla Y,Y blur Z , Z zigoulou X '),
+ self.assertEqual(normalize_expression('X bla Y,Y blur Z , Z zigoulou X '),
'X bla Y, Y blur Z, Z zigoulou X')
class RQLExpressionTC(TestCase):
def test_comparison(self):
- self.assertEquals(ERQLExpression('X is CWUser', 'X', 0),
+ self.assertEqual(ERQLExpression('X is CWUser', 'X', 0),
ERQLExpression('X is CWUser', 'X', 0))
self.assertNotEquals(ERQLExpression('X is CWUser', 'X', 0),
ERQLExpression('X is CWGroup', 'X', 0))
@@ -314,7 +314,7 @@
class GuessRrqlExprMainVarsTC(TestCase):
def test_exists(self):
mainvars = guess_rrqlexpr_mainvars(normalize_expression('NOT EXISTS(O team_competition C, C level < 3)'))
- self.assertEquals(mainvars, 'O')
+ self.assertEqual(mainvars, 'O')
if __name__ == '__main__':
--- a/test/unittest_selectors.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_selectors.py Wed Sep 29 16:16:32 2010 +0200
@@ -17,12 +17,14 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""unit tests for selectors mechanism"""
+from operator import eq, lt, le, gt
from logilab.common.testlib import TestCase, unittest_main
from cubicweb import Binary
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.appobject import Selector, AndSelector, OrSelector
-from cubicweb.selectors import is_instance, adaptable, match_user_groups
+from cubicweb.selectors import (is_instance, adaptable, match_user_groups,
+ multi_lines_rset)
from cubicweb.interfaces import IDownloadable
from cubicweb.web import action
@@ -41,55 +43,55 @@
class SelectorsTC(TestCase):
def test_basic_and(self):
selector = _1_() & _1_()
- self.assertEquals(selector(None), 2)
+ self.assertEqual(selector(None), 2)
selector = _1_() & _0_()
- self.assertEquals(selector(None), 0)
+ self.assertEqual(selector(None), 0)
selector = _0_() & _1_()
- self.assertEquals(selector(None), 0)
+ self.assertEqual(selector(None), 0)
def test_basic_or(self):
selector = _1_() | _1_()
- self.assertEquals(selector(None), 1)
+ self.assertEqual(selector(None), 1)
selector = _1_() | _0_()
- self.assertEquals(selector(None), 1)
+ self.assertEqual(selector(None), 1)
selector = _0_() | _1_()
- self.assertEquals(selector(None), 1)
+ self.assertEqual(selector(None), 1)
selector = _0_() | _0_()
- self.assertEquals(selector(None), 0)
+ self.assertEqual(selector(None), 0)
def test_selector_and_function(self):
selector = _1_() & _2_
- self.assertEquals(selector(None), 3)
+ self.assertEqual(selector(None), 3)
selector = _2_ & _1_()
- self.assertEquals(selector(None), 3)
+ self.assertEqual(selector(None), 3)
def test_three_and(self):
selector = _1_() & _1_() & _1_()
- self.assertEquals(selector(None), 3)
+ self.assertEqual(selector(None), 3)
selector = _1_() & _0_() & _1_()
- self.assertEquals(selector(None), 0)
+ self.assertEqual(selector(None), 0)
selector = _0_() & _1_() & _1_()
- self.assertEquals(selector(None), 0)
+ self.assertEqual(selector(None), 0)
def test_three_or(self):
selector = _1_() | _1_() | _1_()
- self.assertEquals(selector(None), 1)
+ self.assertEqual(selector(None), 1)
selector = _1_() | _0_() | _1_()
- self.assertEquals(selector(None), 1)
+ self.assertEqual(selector(None), 1)
selector = _0_() | _1_() | _1_()
- self.assertEquals(selector(None), 1)
+ self.assertEqual(selector(None), 1)
selector = _0_() | _0_() | _0_()
- self.assertEquals(selector(None), 0)
+ self.assertEqual(selector(None), 0)
def test_composition(self):
selector = (_1_() & _1_()) & (_1_() & _1_())
self.failUnless(isinstance(selector, AndSelector))
- self.assertEquals(len(selector.selectors), 4)
- self.assertEquals(selector(None), 4)
+ self.assertEqual(len(selector.selectors), 4)
+ self.assertEqual(selector(None), 4)
selector = (_1_() & _0_()) | (_1_() & _1_())
self.failUnless(isinstance(selector, OrSelector))
- self.assertEquals(len(selector.selectors), 2)
- self.assertEquals(selector(None), 2)
+ self.assertEqual(len(selector.selectors), 2)
+ self.assertEqual(selector(None), 2)
def test_search_selectors(self):
sel = is_instance('something')
@@ -103,37 +105,37 @@
selector = _1_()
selector &= _1_()
selector &= _1_()
- self.assertEquals(selector(None), 3)
+ self.assertEqual(selector(None), 3)
selector = _1_()
selector &= _0_()
selector &= _1_()
- self.assertEquals(selector(None), 0)
+ self.assertEqual(selector(None), 0)
selector = _0_()
selector &= _1_()
selector &= _1_()
- self.assertEquals(selector(None), 0)
+ self.assertEqual(selector(None), 0)
selector = _0_()
selector &= _0_()
selector &= _0_()
- self.assertEquals(selector(None), 0)
+ self.assertEqual(selector(None), 0)
def test_inplace_or(self):
selector = _1_()
selector |= _1_()
selector |= _1_()
- self.assertEquals(selector(None), 1)
+ self.assertEqual(selector(None), 1)
selector = _1_()
selector |= _0_()
selector |= _1_()
- self.assertEquals(selector(None), 1)
+ self.assertEqual(selector(None), 1)
selector = _0_()
selector |= _1_()
selector |= _1_()
- self.assertEquals(selector(None), 1)
+ self.assertEqual(selector(None), 1)
selector = _0_()
selector |= _0_()
selector |= _0_()
- self.assertEquals(selector(None), 0)
+ self.assertEqual(selector(None), 0)
class ImplementsSelectorTC(CubicWebTC):
@@ -153,7 +155,7 @@
def test_yams_inheritance(self):
cls = self.vreg['etypes'].etype_class('Transition')
- self.assertEquals(is_instance('BaseTransition').score_class(cls, self.request()),
+ self.assertEqual(is_instance('BaseTransition').score_class(cls, self.request()),
3)
@@ -190,6 +192,59 @@
finally:
del self.vreg[SomeAction.__registry__][SomeAction.__regid__]
+
+class MultiLinesRsetSelectorTC(CubicWebTC):
+ def setUp(self):
+ super(MultiLinesRsetSelectorTC, self).setUp()
+ self.req = self.request()
+ self.req.execute('INSERT CWGroup G: G name "group1"')
+ self.req.execute('INSERT CWGroup G: G name "group2"')
+ self.commit()
+ self.rset = self.req.execute('Any G WHERE G is CWGroup')
+
+ def test_default_op_in_selector(self):
+ expected = len(self.rset)
+ selector = multi_lines_rset(expected)
+ self.assertEqual(selector(None, self.req, self.rset), 1)
+ self.assertEqual(selector(None, self.req, None), 0)
+ selector = multi_lines_rset(expected + 1)
+ self.assertEqual(selector(None, self.req, self.rset), 0)
+ self.assertEqual(selector(None, self.req, None), 0)
+ selector = multi_lines_rset(expected - 1)
+ self.assertEqual(selector(None, self.req, self.rset), 0)
+ self.assertEqual(selector(None, self.req, None), 0)
+
+ def test_without_rset(self):
+ expected = len(self.rset)
+ selector = multi_lines_rset(expected)
+ self.assertEqual(selector(None, self.req, None), 0)
+ selector = multi_lines_rset(expected + 1)
+ self.assertEqual(selector(None, self.req, None), 0)
+ selector = multi_lines_rset(expected - 1)
+ self.assertEqual(selector(None, self.req, None), 0)
+
+ def test_with_operators(self):
+ expected = len(self.rset)
+
+ # Format 'expected', 'operator', 'assert'
+ testdata = (( expected, eq, 1),
+ ( expected+1, eq, 0),
+ ( expected-1, eq, 0),
+ ( expected, le, 1),
+ ( expected+1, le, 1),
+ ( expected-1, le, 0),
+ ( expected-1, gt, 1),
+ ( expected, gt, 0),
+ ( expected+1, gt, 0),
+ ( expected+1, lt, 1),
+ ( expected, lt, 0),
+ ( expected-1, lt, 0))
+
+ for (expected, operator, assertion) in testdata:
+ selector = multi_lines_rset(expected, operator)
+ yield self.assertEqual, selector(None, self.req, self.rset), assertion
+
+
if __name__ == '__main__':
unittest_main()
--- a/test/unittest_spa2rql.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_spa2rql.py Wed Sep 29 16:16:32 2010 +0200
@@ -37,7 +37,7 @@
def _test(self, sparql, rql, args={}):
qi = self.tr.translate(sparql)
- self.assertEquals(qi.finalize(), (rql, args))
+ self.assertEqual(qi.finalize(), (rql, args))
def XXX_test_base_01(self):
self._test('SELECT * WHERE { }', 'Any X')
--- a/test/unittest_uilib.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_uilib.py Wed Sep 29 16:16:32 2010 +0200
@@ -36,22 +36,22 @@
]
for text, expected in data:
got = uilib.remove_html_tags(text)
- self.assertEquals(got, expected)
+ self.assertEqual(got, expected)
def test_fallback_safe_cut(self):
- self.assertEquals(uilib.fallback_safe_cut(u'ab <a href="hello">cd</a>', 4), u'ab c...')
- self.assertEquals(uilib.fallback_safe_cut(u'ab <a href="hello">cd</a>', 5), u'ab <a href="hello">cd</a>')
- self.assertEquals(uilib.fallback_safe_cut(u'ab <a href="hello">&d</a>', 4), u'ab &...')
- self.assertEquals(uilib.fallback_safe_cut(u'ab <a href="hello">&d</a> ef', 5), u'ab &d...')
- self.assertEquals(uilib.fallback_safe_cut(u'ab <a href="hello">ìd</a>', 4), u'ab ì...')
- self.assertEquals(uilib.fallback_safe_cut(u'& <a href="hello">&d</a> ef', 4), u'& &d...')
+ self.assertEqual(uilib.fallback_safe_cut(u'ab <a href="hello">cd</a>', 4), u'ab c...')
+ self.assertEqual(uilib.fallback_safe_cut(u'ab <a href="hello">cd</a>', 5), u'ab <a href="hello">cd</a>')
+ self.assertEqual(uilib.fallback_safe_cut(u'ab <a href="hello">&d</a>', 4), u'ab &...')
+ self.assertEqual(uilib.fallback_safe_cut(u'ab <a href="hello">&d</a> ef', 5), u'ab &d...')
+ self.assertEqual(uilib.fallback_safe_cut(u'ab <a href="hello">ìd</a>', 4), u'ab ì...')
+ self.assertEqual(uilib.fallback_safe_cut(u'& <a href="hello">&d</a> ef', 4), u'& &d...')
def test_lxml_safe_cut(self):
- self.assertEquals(uilib.safe_cut(u'aaa<div>aaad</div> ef', 4), u'<p>aaa</p><div>a...</div>')
- self.assertEquals(uilib.safe_cut(u'aaa<div>aaad</div> ef', 7), u'<p>aaa</p><div>aaad</div>...')
- self.assertEquals(uilib.safe_cut(u'aaa<div>aaad</div>', 7), u'<p>aaa</p><div>aaad</div>')
+ self.assertEqual(uilib.safe_cut(u'aaa<div>aaad</div> ef', 4), u'<p>aaa</p><div>a...</div>')
+ self.assertEqual(uilib.safe_cut(u'aaa<div>aaad</div> ef', 7), u'<p>aaa</p><div>aaad</div>...')
+ self.assertEqual(uilib.safe_cut(u'aaa<div>aaad</div>', 7), u'<p>aaa</p><div>aaad</div>')
# Missing ellipsis due to space management but we don't care
- self.assertEquals(uilib.safe_cut(u'ab <a href="hello">&d</a>', 4), u'<p>ab <a href="hello">&...</a></p>')
+ self.assertEqual(uilib.safe_cut(u'ab <a href="hello">&d</a>', 4), u'<p>ab <a href="hello">&...</a></p>')
def test_cut(self):
"""tests uilib.cut() behaviour"""
@@ -62,7 +62,7 @@
]
for text, expected in data:
got = uilib.cut(text, 8)
- self.assertEquals(got, expected)
+ self.assertEqual(got, expected)
def test_text_cut(self):
"""tests uilib.text_cut() behaviour with no text"""
@@ -89,62 +89,62 @@
]
for text, expected in data:
got = uilib.text_cut(text, 30)
- self.assertEquals(got, expected)
+ self.assertEqual(got, expected)
def test_soup2xhtml_1_1(self):
- self.assertEquals(uilib.soup2xhtml('hop <div>', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('hop <div>', 'ascii'),
'hop <div/>')
- self.assertEquals(uilib.soup2xhtml('<div> hop', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('<div> hop', 'ascii'),
'<div> hop</div>')
- self.assertEquals(uilib.soup2xhtml('hop <div> hop', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('hop <div> hop', 'ascii'),
'hop <div> hop</div>')
def test_soup2xhtml_1_2(self):
- self.assertEquals(uilib.soup2xhtml('hop </div>', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('hop </div>', 'ascii'),
'hop ')
- self.assertEquals(uilib.soup2xhtml('</div> hop', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('</div> hop', 'ascii'),
'<div/> hop')
- self.assertEquals(uilib.soup2xhtml('hop </div> hop', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('hop </div> hop', 'ascii'),
'<div>hop </div> hop')
def test_soup2xhtml_2_1(self):
- self.assertEquals(uilib.soup2xhtml('hop <body>', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('hop <body>', 'ascii'),
'hop ')
- self.assertEquals(uilib.soup2xhtml('<body> hop', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('<body> hop', 'ascii'),
' hop')
- self.assertEquals(uilib.soup2xhtml('hop <body> hop', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('hop <body> hop', 'ascii'),
'hop hop')
def test_soup2xhtml_2_2(self):
- self.assertEquals(uilib.soup2xhtml('hop </body>', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('hop </body>', 'ascii'),
'hop ')
- self.assertEquals(uilib.soup2xhtml('</body> hop', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('</body> hop', 'ascii'),
' hop')
- self.assertEquals(uilib.soup2xhtml('hop </body> hop', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('hop </body> hop', 'ascii'),
'hop hop')
def test_soup2xhtml_3_1(self):
- self.assertEquals(uilib.soup2xhtml('hop <html>', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('hop <html>', 'ascii'),
'hop ')
- self.assertEquals(uilib.soup2xhtml('<html> hop', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('<html> hop', 'ascii'),
' hop')
- self.assertEquals(uilib.soup2xhtml('hop <html> hop', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('hop <html> hop', 'ascii'),
'hop hop')
def test_soup2xhtml_3_2(self):
- self.assertEquals(uilib.soup2xhtml('hop </html>', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('hop </html>', 'ascii'),
'hop ')
- self.assertEquals(uilib.soup2xhtml('</html> hop', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('</html> hop', 'ascii'),
' hop')
- self.assertEquals(uilib.soup2xhtml('hop </html> hop', 'ascii'),
+ self.assertEqual(uilib.soup2xhtml('hop </html> hop', 'ascii'),
'hop hop')
def test_js(self):
- self.assertEquals(str(uilib.js.pouet(1, "2")),
+ self.assertEqual(str(uilib.js.pouet(1, "2")),
'pouet(1,"2")')
- self.assertEquals(str(uilib.js.cw.pouet(1, "2")),
+ self.assertEqual(str(uilib.js.cw.pouet(1, "2")),
'cw.pouet(1,"2")')
- self.assertEquals(str(uilib.js.cw.pouet(1, "2").pouet(None)),
+ self.assertEqual(str(uilib.js.cw.pouet(1, "2").pouet(None)),
'cw.pouet(1,"2").pouet(null)')
if __name__ == '__main__':
--- a/test/unittest_utils.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_utils.py Wed Sep 29 16:16:32 2010 +0200
@@ -57,47 +57,47 @@
def test_base(self):
l = RepeatList(3, (1, 3))
- self.assertEquals(l[0], (1, 3))
- self.assertEquals(l[2], (1, 3))
- self.assertEquals(l[-1], (1, 3))
- self.assertEquals(len(l), 3)
+ self.assertEqual(l[0], (1, 3))
+ self.assertEqual(l[2], (1, 3))
+ self.assertEqual(l[-1], (1, 3))
+ self.assertEqual(len(l), 3)
# XXX
- self.assertEquals(l[4], (1, 3))
+ self.assertEqual(l[4], (1, 3))
self.failIf(RepeatList(0, None))
def test_slice(self):
l = RepeatList(3, (1, 3))
- self.assertEquals(l[0:1], [(1, 3)])
- self.assertEquals(l[0:4], [(1, 3)]*3)
- self.assertEquals(l[:], [(1, 3)]*3)
+ self.assertEqual(l[0:1], [(1, 3)])
+ self.assertEqual(l[0:4], [(1, 3)]*3)
+ self.assertEqual(l[:], [(1, 3)]*3)
def test_iter(self):
- self.assertEquals(list(RepeatList(3, (1, 3))),
+ self.assertEqual(list(RepeatList(3, (1, 3))),
[(1, 3)]*3)
def test_add(self):
l = RepeatList(3, (1, 3))
- self.assertEquals(l + [(1, 4)], [(1, 3)]*3 + [(1, 4)])
- self.assertEquals([(1, 4)] + l, [(1, 4)] + [(1, 3)]*3)
- self.assertEquals(l + RepeatList(2, (2, 3)), [(1, 3)]*3 + [(2, 3)]*2)
+ self.assertEqual(l + [(1, 4)], [(1, 3)]*3 + [(1, 4)])
+ self.assertEqual([(1, 4)] + l, [(1, 4)] + [(1, 3)]*3)
+ self.assertEqual(l + RepeatList(2, (2, 3)), [(1, 3)]*3 + [(2, 3)]*2)
x = l + RepeatList(2, (1, 3))
self.assertIsInstance(x, RepeatList)
- self.assertEquals(len(x), 5)
- self.assertEquals(x[0], (1, 3))
+ self.assertEqual(len(x), 5)
+ self.assertEqual(x[0], (1, 3))
x = l + [(1, 3)] * 2
- self.assertEquals(x, [(1, 3)] * 5)
+ self.assertEqual(x, [(1, 3)] * 5)
def test_eq(self):
- self.assertEquals(RepeatList(3, (1, 3)),
+ self.assertEqual(RepeatList(3, (1, 3)),
[(1, 3)]*3)
def test_pop(self):
l = RepeatList(3, (1, 3))
l.pop(2)
- self.assertEquals(l, [(1, 3)]*2)
+ self.assertEqual(l, [(1, 3)]*2)
class SizeConstrainedListTC(TestCase):
@@ -106,7 +106,7 @@
l = SizeConstrainedList(10)
for i in xrange(12):
l.append(i)
- self.assertEquals(l, range(2, 12))
+ self.assertEqual(l, range(2, 12))
def test_extend(self):
testdata = [(range(5), range(5)),
@@ -116,44 +116,44 @@
for extension, expected in testdata:
l = SizeConstrainedList(10)
l.extend(extension)
- yield self.assertEquals, l, expected
+ yield self.assertEqual, l, expected
class JSONEncoderTC(TestCase):
def setUp(self):
if json is None:
- self.skip('json not available')
+ self.skipTest('json not available')
def encode(self, value):
return json.dumps(value, cls=CubicWebJsonEncoder)
def test_encoding_dates(self):
- self.assertEquals(self.encode(datetime.datetime(2009, 9, 9, 20, 30)),
+ self.assertEqual(self.encode(datetime.datetime(2009, 9, 9, 20, 30)),
'"2009/09/09 20:30:00"')
- self.assertEquals(self.encode(datetime.date(2009, 9, 9)),
+ self.assertEqual(self.encode(datetime.date(2009, 9, 9)),
'"2009/09/09"')
- self.assertEquals(self.encode(datetime.time(20, 30)),
+ self.assertEqual(self.encode(datetime.time(20, 30)),
'"20:30:00"')
def test_encoding_decimal(self):
- self.assertEquals(self.encode(decimal.Decimal('1.2')), '1.2')
+ self.assertEqual(self.encode(decimal.Decimal('1.2')), '1.2')
def test_encoding_bare_entity(self):
e = Entity(None)
e.cw_attr_cache['pouet'] = 'hop'
e.eid = 2
- self.assertEquals(json.loads(self.encode(e)),
+ self.assertEqual(json.loads(self.encode(e)),
{'pouet': 'hop', 'eid': 2})
def test_encoding_entity_in_list(self):
e = Entity(None)
e.cw_attr_cache['pouet'] = 'hop'
e.eid = 2
- self.assertEquals(json.loads(self.encode([e])),
+ self.assertEqual(json.loads(self.encode([e])),
[{'pouet': 'hop', 'eid': 2}])
def test_encoding_unknown_stuff(self):
- self.assertEquals(self.encode(TestCase), 'null')
+ self.assertEqual(self.encode(TestCase), 'null')
if __name__ == '__main__':
--- a/test/unittest_vregistry.py Thu Sep 23 23:28:58 2010 +0200
+++ b/test/unittest_vregistry.py Wed Sep 29 16:16:32 2010 +0200
@@ -48,9 +48,9 @@
self.vreg.load_file(join(BASE, 'entities', '__init__.py'), 'cubicweb.entities.__init__')
self.vreg.load_file(join(WEBVIEWSDIR, 'idownloadable.py'), 'cubicweb.web.views.idownloadable')
self.vreg.load_file(join(WEBVIEWSDIR, 'primary.py'), 'cubicweb.web.views.primary')
- self.assertEquals(len(self.vreg['views']['primary']), 2)
+ self.assertEqual(len(self.vreg['views']['primary']), 2)
self.vreg.initialization_completed()
- self.assertEquals(len(self.vreg['views']['primary']), 1)
+ self.assertEqual(len(self.vreg['views']['primary']), 1)
def test_load_subinterface_based_appobjects(self):
@@ -70,7 +70,7 @@
self.vreg.register(CardIProgressAdapter)
self.vreg.initialization_completed()
# check progressbar isn't kicked
- self.assertEquals(len(self.vreg['views']['progressbar']), 1)
+ self.assertEqual(len(self.vreg['views']['progressbar']), 1)
def test_properties(self):
self.vreg.reset()
@@ -84,7 +84,7 @@
def test_property_default_overriding(self):
# see data/views.py
from cubicweb.web.views.xmlrss import RSSIconBox
- self.assertEquals(self.vreg.property_info(RSSIconBox._cwpropkey('visible'))['default'], True)
+ self.assertEqual(self.vreg.property_info(RSSIconBox._cwpropkey('visible'))['default'], True)
if __name__ == '__main__':
unittest_main()
--- a/vregistry.py Thu Sep 23 23:28:58 2010 +0200
+++ b/vregistry.py Wed Sep 29 16:16:32 2010 +0200
@@ -46,6 +46,7 @@
from cubicweb import RegistryNotFound, ObjectNotFound, NoSelectableObject
from cubicweb.appobject import AppObject, class_regid
+
def _toload_info(path, extrapath, _toload=None):
"""return a dictionary of <modname>: <modpath> and an ordered list of
(file, module name) to load
@@ -221,17 +222,14 @@
elif appobjectscore > 0 and appobjectscore == score:
winners.append(appobject)
if winners is None:
- raise NoSelectableObject('args: %s\nkwargs: %s %s'
- % (args, kwargs.keys(),
- [repr(v) for v in appobjects]))
+ raise NoSelectableObject(args, kwargs, appobjects)
if len(winners) > 1:
# log in production environement / test, error while debugging
+ msg = 'select ambiguity: %s\n(args: %s, kwargs: %s)'
if self.config.debugmode or self.config.mode == 'test':
- raise Exception('select ambiguity, args: %s\nkwargs: %s %s'
- % (args, kwargs.keys(),
- [repr(v) for v in winners]))
- self.error('select ambiguity, args: %s\nkwargs: %s %s',
- args, kwargs.keys(), [repr(v) for v in winners])
+ # raise bare exception in debug mode
+ raise Exception(msg % (winners, self.args, self.kwargs.keys()))
+ self.error(msg, winners, self.args, self.kwargs.keys())
# return the result of calling the appobject
return winners[0](*args, **kwargs)
--- a/web/data/cubicweb.css Thu Sep 23 23:28:58 2010 +0200
+++ b/web/data/cubicweb.css Wed Sep 29 16:16:32 2010 +0200
@@ -201,6 +201,18 @@
display: inline;
}
+.caption {
+ font-weight: bold;
+}
+
+.legend{
+ font-style: italic;
+}
+
+.align-center{
+ text-align: center;
+}
+
/***************************************/
/* LAYOUT */
/***************************************/
--- a/web/data/cubicweb.old.css Thu Sep 23 23:28:58 2010 +0200
+++ b/web/data/cubicweb.old.css Wed Sep 29 16:16:32 2010 +0200
@@ -208,6 +208,17 @@
display: inline;
}
+.caption {
+ font-weight: bold;
+}
+
+.legend{
+ font-style: italic;
+}
+
+.align-center{
+ text-align: center;
+}
/***************************************/
/* LAYOUT */
--- a/web/facet.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/facet.py Wed Sep 29 16:16:32 2010 +0200
@@ -64,6 +64,14 @@
from cubicweb.appobject import AppObject
from cubicweb.web.htmlwidgets import HTMLWidget
+
+def rtype_facet_title(facet):
+ ptypes = facet.cw_rset.column_types(0)
+ if len(ptypes) == 1:
+ return display_name(facet._cw, facet.rtype, form=facet.role,
+ context=iter(ptypes).next())
+ return display_name(facet._cw, facet.rtype, form=facet.role)
+
## rqlst manipulation functions used by facets ################################
def prepare_facets_rqlst(rqlst, args=None):
@@ -511,9 +519,7 @@
# internal purpose
_select_target_entity = True
- @property
- def title(self):
- return display_name(self._cw, self.rtype, form=self.role)
+ title = property(rtype_facet_title)
@property
def rql_sort(self):
@@ -888,9 +894,7 @@
rtype = None # override me in subclass
role = 'subject' # role of filtered entity in the relation
- @property
- def title(self):
- return display_name(self._cw, self.rtype, self.role)
+ title = property(rtype_facet_title)
def support_and(self):
return False
--- a/web/request.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/request.py Wed Sep 29 16:16:32 2010 +0200
@@ -531,7 +531,7 @@
"""set output content type for this request. An optional filename
may be given
"""
- if content_type.startswith('text/'):
+ if content_type.startswith('text/') and ';charset=' not in content_type:
content_type += ';charset=' + (encoding or self.encoding)
self.set_header('content-type', content_type)
if filename:
--- a/web/test/test_views.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/test_views.py Wed Sep 29 16:16:32 2010 +0200
@@ -66,7 +66,7 @@
self.vreg.register(SomeView)
rset = self.execute('CWUser X')
source = self.view('someview', rset).source
- self.assertEquals(source.count('spam.js'), 1)
+ self.assertEqual(source.count('spam.js'), 1)
--- a/web/test/unittest_application.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_application.py Wed Sep 29 16:16:32 2010 +0200
@@ -69,32 +69,32 @@
def test_list_arg(self):
"""tests the list_arg() function"""
list_arg = self._cw.list_form_param
- self.assertEquals(list_arg('arg3', {}), [])
+ self.assertEqual(list_arg('arg3', {}), [])
d = {'arg1' : "value1",
'arg2' : ('foo', INTERNAL_FIELD_VALUE,),
'arg3' : ['bar']}
- self.assertEquals(list_arg('arg1', d, True), ['value1'])
- self.assertEquals(d, {'arg2' : ('foo', INTERNAL_FIELD_VALUE), 'arg3' : ['bar'],})
- self.assertEquals(list_arg('arg2', d, True), ['foo'])
- self.assertEquals({'arg3' : ['bar'],}, d)
- self.assertEquals(list_arg('arg3', d), ['bar',])
- self.assertEquals({'arg3' : ['bar'],}, d)
+ self.assertEqual(list_arg('arg1', d, True), ['value1'])
+ self.assertEqual(d, {'arg2' : ('foo', INTERNAL_FIELD_VALUE), 'arg3' : ['bar'],})
+ self.assertEqual(list_arg('arg2', d, True), ['foo'])
+ self.assertEqual({'arg3' : ['bar'],}, d)
+ self.assertEqual(list_arg('arg3', d), ['bar',])
+ self.assertEqual({'arg3' : ['bar'],}, d)
def test_from_controller(self):
self._cw.vreg['controllers'] = {'view': 1, 'login': 1}
- self.assertEquals(self._cw.from_controller(), 'view')
+ self.assertEqual(self._cw.from_controller(), 'view')
req = FakeRequest(url='project?vid=list')
req.vreg['controllers'] = {'view': 1, 'login': 1}
# this assertion is just to make sure that relative_path can be
# correctly computed as it is used in from_controller()
- self.assertEquals(req.relative_path(False), 'project')
- self.assertEquals(req.from_controller(), 'view')
+ self.assertEqual(req.relative_path(False), 'project')
+ self.assertEqual(req.from_controller(), 'view')
# test on a valid non-view controller
req = FakeRequest(url='login?x=1&y=2')
req.vreg['controllers'] = {'view': 1, 'login': 1}
- self.assertEquals(req.relative_path(False), 'login')
- self.assertEquals(req.from_controller(), 'login')
+ self.assertEqual(req.relative_path(False), 'login')
+ self.assertEqual(req.from_controller(), 'login')
class UtilsTC(TestCase):
@@ -107,22 +107,22 @@
# """tests which mapping is used (application or core)"""
# init_mapping()
# from cubicweb.common import mapping
- # self.assertEquals(mapping.MAPPING_USED, 'core')
+ # self.assertEqual(mapping.MAPPING_USED, 'core')
# sys.modules['mapping'] = FakeMapping()
# init_mapping()
- # self.assertEquals(mapping.MAPPING_USED, 'application')
+ # self.assertEqual(mapping.MAPPING_USED, 'application')
# del sys.modules['mapping']
def test_execute_linkto(self):
"""tests the execute_linkto() function"""
- self.assertEquals(self.ctrl.execute_linkto(), None)
- self.assertEquals(self.ctrl._cursor.executed,
+ self.assertEqual(self.ctrl.execute_linkto(), None)
+ self.assertEqual(self.ctrl._cursor.executed,
[])
self.ctrl.set_form({'__linkto' : 'works_for:12_13_14:object',
'eid': 8})
self.ctrl.execute_linkto()
- self.assertEquals(self.ctrl._cursor.executed,
+ self.assertEqual(self.ctrl._cursor.executed,
['SET Y works_for X WHERE X eid 8, Y eid %s' % i
for i in (12, 13, 14)])
@@ -130,7 +130,7 @@
self.ctrl.set_form({'__linkto' : 'works_for:12_13_14:subject',
'eid': 8})
self.ctrl.execute_linkto()
- self.assertEquals(self.ctrl._cursor.executed,
+ self.assertEqual(self.ctrl._cursor.executed,
['SET X works_for Y WHERE X eid 8, Y eid %s' % i
for i in (12, 13, 14)])
@@ -138,14 +138,14 @@
self.ctrl.new_cursor()
self.ctrl._cw.form = {'__linkto' : 'works_for:12_13_14:object'}
self.ctrl.execute_linkto(eid=8)
- self.assertEquals(self.ctrl._cursor.executed,
+ self.assertEqual(self.ctrl._cursor.executed,
['SET Y works_for X WHERE X eid 8, Y eid %s' % i
for i in (12, 13, 14)])
self.ctrl.new_cursor()
self.ctrl.set_form({'__linkto' : 'works_for:12_13_14:subject'})
self.ctrl.execute_linkto(eid=8)
- self.assertEquals(self.ctrl._cursor.executed,
+ self.assertEqual(self.ctrl._cursor.executed,
['SET X works_for Y WHERE X eid 8, Y eid %s' % i
for i in (12, 13, 14)])
@@ -159,13 +159,13 @@
def test_cnx_user_groups_sync(self):
user = self.user()
- self.assertEquals(user.groups, set(('managers',)))
+ self.assertEqual(user.groups, set(('managers',)))
self.execute('SET X in_group G WHERE X eid %s, G name "guests"' % user.eid)
user = self.user()
- self.assertEquals(user.groups, set(('managers',)))
+ self.assertEqual(user.groups, set(('managers',)))
self.commit()
user = self.user()
- self.assertEquals(user.groups, set(('managers', 'guests')))
+ self.assertEqual(user.groups, set(('managers', 'guests')))
# cleanup
self.execute('DELETE X in_group G WHERE X eid %s, G name "guests"' % user.eid)
self.commit()
@@ -193,13 +193,13 @@
path, params = self.expect_redirect(lambda x: self.app_publish(x, 'edit'), req)
forminfo = req.session.data['view?vid=edition...']
eidmap = forminfo['eidmap']
- self.assertEquals(eidmap, {})
+ self.assertEqual(eidmap, {})
values = forminfo['values']
- self.assertEquals(values['login-subject:'+eid], '')
- self.assertEquals(values['eid'], eid)
+ self.assertEqual(values['login-subject:'+eid], '')
+ self.assertEqual(values['eid'], eid)
error = forminfo['error']
- self.assertEquals(error.entity, user.eid)
- self.assertEquals(error.errors['login-subject'], 'required field')
+ self.assertEqual(error.entity, user.eid)
+ self.assertEqual(error.errors['login-subject'], 'required field')
def test_validation_error_dont_loose_subentity_data_ctrl(self):
@@ -222,13 +222,13 @@
}
path, params = self.expect_redirect(lambda x: self.app_publish(x, 'edit'), req)
forminfo = req.session.data['view?vid=edition...']
- self.assertEquals(set(forminfo['eidmap']), set('XY'))
- self.assertEquals(forminfo['eidmap']['X'], None)
+ self.assertEqual(set(forminfo['eidmap']), set('XY'))
+ self.assertEqual(forminfo['eidmap']['X'], None)
self.assertIsInstance(forminfo['eidmap']['Y'], int)
- self.assertEquals(forminfo['error'].entity, 'X')
- self.assertEquals(forminfo['error'].errors,
+ self.assertEqual(forminfo['error'].entity, 'X')
+ self.assertEqual(forminfo['error'].errors,
{'login-subject': 'required field'})
- self.assertEquals(forminfo['values'], req.form)
+ self.assertEqual(forminfo['values'], req.form)
def test_validation_error_dont_loose_subentity_data_repo(self):
@@ -251,13 +251,13 @@
}
path, params = self.expect_redirect(lambda x: self.app_publish(x, 'edit'), req)
forminfo = req.session.data['view?vid=edition...']
- self.assertEquals(set(forminfo['eidmap']), set('XY'))
+ self.assertEqual(set(forminfo['eidmap']), set('XY'))
self.assertIsInstance(forminfo['eidmap']['X'], int)
self.assertIsInstance(forminfo['eidmap']['Y'], int)
- self.assertEquals(forminfo['error'].entity, forminfo['eidmap']['X'])
- self.assertEquals(forminfo['error'].errors,
+ self.assertEqual(forminfo['error'].entity, forminfo['eidmap']['X'])
+ self.assertEqual(forminfo['error'].errors,
{'login-subject': u'the value "admin" is already used, use another one'})
- self.assertEquals(forminfo['values'], req.form)
+ self.assertEqual(forminfo['values'], req.form)
def _test_cleaned(self, kwargs, injected, cleaned):
@@ -282,24 +282,24 @@
# protocol
vreg = self.app.vreg
# default value
- self.assertEquals(vreg.property_value('ui.language'), 'en')
+ self.assertEqual(vreg.property_value('ui.language'), 'en')
self.execute('INSERT CWProperty X: X value "fr", X pkey "ui.language"')
- self.assertEquals(vreg.property_value('ui.language'), 'en')
+ self.assertEqual(vreg.property_value('ui.language'), 'en')
self.commit()
- self.assertEquals(vreg.property_value('ui.language'), 'fr')
+ self.assertEqual(vreg.property_value('ui.language'), 'fr')
self.execute('SET X value "de" WHERE X pkey "ui.language"')
- self.assertEquals(vreg.property_value('ui.language'), 'fr')
+ self.assertEqual(vreg.property_value('ui.language'), 'fr')
self.commit()
- self.assertEquals(vreg.property_value('ui.language'), 'de')
+ self.assertEqual(vreg.property_value('ui.language'), 'de')
self.execute('DELETE CWProperty X WHERE X pkey "ui.language"')
- self.assertEquals(vreg.property_value('ui.language'), 'de')
+ self.assertEqual(vreg.property_value('ui.language'), 'de')
self.commit()
- self.assertEquals(vreg.property_value('ui.language'), 'en')
+ self.assertEqual(vreg.property_value('ui.language'), 'en')
def test_login_not_available_to_authenticated(self):
req = self.request()
ex = self.assertRaises(Unauthorized, self.app_publish, req, 'login')
- self.assertEquals(str(ex), 'log out first')
+ self.assertEqual(str(ex), 'log out first')
def test_fb_login_concept(self):
"""see data/views.py"""
@@ -311,7 +311,7 @@
req.form['__fblogin'] = u'turlututu'
page = self.app_publish(req)
self.failIf(req.cnx is origcnx)
- self.assertEquals(req.user.login, 'turlututu')
+ self.assertEqual(req.user.login, 'turlututu')
self.failUnless('turlututu' in page, page)
# authentication tests ####################################################
@@ -320,13 +320,13 @@
req, origsession = self.init_authentication('http')
self.assertAuthFailure(req)
self.assertRaises(AuthenticationError, self.app_publish, req, 'login')
- self.assertEquals(req.cnx, None)
+ self.assertEqual(req.cnx, None)
authstr = base64.encodestring('%s:%s' % (origsession.login, origsession.authinfo['password']))
req._headers['Authorization'] = 'basic %s' % authstr
self.assertAuthSuccess(req, origsession)
- self.assertEquals(req.session.authinfo, {'password': origsession.authinfo['password']})
+ self.assertEqual(req.session.authinfo, {'password': origsession.authinfo['password']})
self.assertRaises(LogOut, self.app_publish, req, 'logout')
- self.assertEquals(len(self.open_sessions), 0)
+ self.assertEqual(len(self.open_sessions), 0)
def test_cookie_auth_no_anon(self):
req, origsession = self.init_authentication('cookie')
@@ -334,13 +334,13 @@
form = self.app_publish(req, 'login')
self.failUnless('__login' in form)
self.failUnless('__password' in form)
- self.assertEquals(req.cnx, None)
+ self.assertEqual(req.cnx, None)
req.form['__login'] = origsession.login
req.form['__password'] = origsession.authinfo['password']
self.assertAuthSuccess(req, origsession)
- self.assertEquals(req.session.authinfo, {'password': origsession.authinfo['password']})
+ self.assertEqual(req.session.authinfo, {'password': origsession.authinfo['password']})
self.assertRaises(LogOut, self.app_publish, req, 'logout')
- self.assertEquals(len(self.open_sessions), 0)
+ self.assertEqual(len(self.open_sessions), 0)
def test_login_by_email(self):
login = self.request().user.login
@@ -359,9 +359,9 @@
req.form['__login'] = address
req.form['__password'] = origsession.authinfo['password']
self.assertAuthSuccess(req, origsession)
- self.assertEquals(req.session.authinfo, {'password': origsession.authinfo['password']})
+ self.assertEqual(req.session.authinfo, {'password': origsession.authinfo['password']})
self.assertRaises(LogOut, self.app_publish, req, 'logout')
- self.assertEquals(len(self.open_sessions), 0)
+ self.assertEqual(len(self.open_sessions), 0)
def _reset_cookie(self, req):
# preparing the suite of the test
@@ -376,18 +376,18 @@
def _test_auth_anon(self, req):
self.app.connect(req)
asession = req.session
- self.assertEquals(len(self.open_sessions), 1)
- self.assertEquals(asession.login, 'anon')
- self.assertEquals(asession.authinfo['password'], 'anon')
+ self.assertEqual(len(self.open_sessions), 1)
+ self.assertEqual(asession.login, 'anon')
+ self.assertEqual(asession.authinfo['password'], 'anon')
self.failUnless(asession.anonymous_session)
self._reset_cookie(req)
def _test_anon_auth_fail(self, req):
- self.assertEquals(len(self.open_sessions), 1)
+ self.assertEqual(len(self.open_sessions), 1)
self.app.connect(req)
- self.assertEquals(req.message, 'authentication failure')
- self.assertEquals(req.session.anonymous_session, True)
- self.assertEquals(len(self.open_sessions), 1)
+ self.assertEqual(req.message, 'authentication failure')
+ self.assertEqual(req.session.anonymous_session, True)
+ self.assertEqual(len(self.open_sessions), 1)
self._reset_cookie(req)
def test_http_auth_anon_allowed(self):
@@ -399,9 +399,9 @@
authstr = base64.encodestring('%s:%s' % (origsession.login, origsession.authinfo['password']))
req._headers['Authorization'] = 'basic %s' % authstr
self.assertAuthSuccess(req, origsession)
- self.assertEquals(req.session.authinfo, {'password': origsession.authinfo['password']})
+ self.assertEqual(req.session.authinfo, {'password': origsession.authinfo['password']})
self.assertRaises(LogOut, self.app_publish, req, 'logout')
- self.assertEquals(len(self.open_sessions), 0)
+ self.assertEqual(len(self.open_sessions), 0)
def test_cookie_auth_anon_allowed(self):
req, origsession = self.init_authentication('cookie', 'anon')
@@ -412,10 +412,10 @@
req.form['__login'] = origsession.login
req.form['__password'] = origsession.authinfo['password']
self.assertAuthSuccess(req, origsession)
- self.assertEquals(req.session.authinfo,
+ self.assertEqual(req.session.authinfo,
{'password': origsession.authinfo['password']})
self.assertRaises(LogOut, self.app_publish, req, 'logout')
- self.assertEquals(len(self.open_sessions), 0)
+ self.assertEqual(len(self.open_sessions), 0)
def test_non_regr_optional_first_var(self):
req = self.request()
--- a/web/test/unittest_breadcrumbs.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_breadcrumbs.py Wed Sep 29 16:16:32 2010 +0200
@@ -28,11 +28,11 @@
self.execute('SET F2 filed_under F1 WHERE F1 eid %(f1)s, F2 eid %(f2)s',
{'f1' : f1.eid, 'f2' : f2.eid})
self.commit()
- self.assertEquals(f2.view('breadcrumbs'),
+ self.assertEqual(f2.view('breadcrumbs'),
'<a href="http://testing.fr/cubicweb/folder/%s" title="">chi&ld</a>' % f2.eid)
childrset = f2.as_rset()
ibc = self.vreg['components'].select('breadcrumbs', self.request(), rset=childrset)
- self.assertEquals(ibc.render(),
+ self.assertEqual(ibc.render(),
"""<span id="breadcrumbs" class="pathbar"> > <a href="http://testing.fr/cubicweb/Folder">folder_plural</a> > <a href="http://testing.fr/cubicweb/folder/%s" title="">par&ent</a> > 
<a href="http://testing.fr/cubicweb/folder/%s" title="">chi&ld</a></span>""" % (f1.eid, f2.eid))
--- a/web/test/unittest_facet.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_facet.py Wed Sep 29 16:16:32 2010 +0200
@@ -9,12 +9,12 @@
rqlst = rset.syntax_tree().copy()
req.vreg.rqlhelper.annotate(rqlst)
mainvar, baserql = facet.prepare_facets_rqlst(rqlst, rset.args)
- self.assertEquals(mainvar.name, 'X')
- self.assertEquals(baserql, 'Any X WHERE X is CWUser')
- self.assertEquals(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ self.assertEqual(mainvar.name, 'X')
+ self.assertEqual(baserql, 'Any X WHERE X is CWUser')
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
return req, rset, rqlst, mainvar
- def test_relation(self):
+ def test_relation_simple(self):
req, rset, rqlst, mainvar = self.prepare_rqlst()
f = facet.RelationFacet(req, rset=rset,
rqlst=rqlst.children[0],
@@ -24,22 +24,55 @@
f.target_attr = 'name'
guests, managers = [eid for eid, in self.execute('CWGroup G ORDERBY GN '
'WHERE G name GN, G name IN ("guests", "managers")')]
- self.assertEquals(f.vocabulary(),
+ self.assertEqual(f.vocabulary(),
[(u'guests', guests), (u'managers', managers)])
# ensure rqlst is left unmodified
- self.assertEquals(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
#rqlst = rset.syntax_tree()
- self.assertEquals(f.possible_values(),
+ self.assertEqual(f.possible_values(),
[str(guests), str(managers)])
# ensure rqlst is left unmodified
- self.assertEquals(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
req.form[f.__regid__] = str(guests)
f.add_rql_restrictions()
# selection is cluttered because rqlst has been prepared for facet (it
# is not in real life)
- self.assertEquals(f.rqlst.as_string(),
+ self.assertEqual(f.rqlst.as_string(),
'DISTINCT Any WHERE X is CWUser, X in_group D, D eid %s' % guests)
+ def test_relation_optional_rel(self):
+ req = self.request()
+ rset = self.execute('Any X,GROUP_CONCAT(GN) GROUPBY X '
+ 'WHERE X in_group G?, G name GN, NOT G name "users"')
+ rqlst = rset.syntax_tree().copy()
+ req.vreg.rqlhelper.annotate(rqlst)
+ mainvar, baserql = facet.prepare_facets_rqlst(rqlst, rset.args)
+
+ f = facet.RelationFacet(req, rset=rset,
+ rqlst=rqlst.children[0],
+ filtered_variable=mainvar)
+ f.rtype = 'in_group'
+ f.role = 'subject'
+ f.target_attr = 'name'
+ guests, managers = [eid for eid, in self.execute('CWGroup G ORDERBY GN '
+ 'WHERE G name GN, G name IN ("guests", "managers")')]
+ self.assertEqual(f.vocabulary(),
+ [(u'guests', guests), (u'managers', managers)])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any GROUPBY X WHERE X in_group G?, G name GN, NOT G name "users"')
+ #rqlst = rset.syntax_tree()
+ self.assertEqual(sorted(f.possible_values()),
+ [str(guests), str(managers)])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any GROUPBY X WHERE X in_group G?, G name GN, NOT G name "users"')
+ req.form[f.__regid__] = str(guests)
+ f.add_rql_restrictions()
+ # selection is cluttered because rqlst has been prepared for facet (it
+ # is not in real life)
+ self.assertEqual(f.rqlst.as_string(),
+ 'DISTINCT Any GROUPBY X WHERE X in_group G?, G name GN, NOT G name "users", X in_group D, D eid %s' % guests)
+
+
def test_relationattribute(self):
req, rset, rqlst, mainvar = self.prepare_rqlst()
f = facet.RelationAttributeFacet(req, rset=rset,
@@ -48,20 +81,20 @@
f.rtype = 'in_group'
f.role = 'subject'
f.target_attr = 'name'
- self.assertEquals(f.vocabulary(),
+ self.assertEqual(f.vocabulary(),
[(u'guests', u'guests'), (u'managers', u'managers')])
# ensure rqlst is left unmodified
- self.assertEquals(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
#rqlst = rset.syntax_tree()
- self.assertEquals(f.possible_values(),
+ self.assertEqual(f.possible_values(),
['guests', 'managers'])
# ensure rqlst is left unmodified
- self.assertEquals(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
req.form[f.__regid__] = 'guests'
f.add_rql_restrictions()
# selection is cluttered because rqlst has been prepared for facet (it
# is not in real life)
- self.assertEquals(f.rqlst.as_string(),
+ self.assertEqual(f.rqlst.as_string(),
"DISTINCT Any WHERE X is CWUser, X in_group E, E name 'guests'")
@@ -71,18 +104,18 @@
rqlst=rqlst.children[0],
filtered_variable=mainvar)
f.rtype = 'login'
- self.assertEquals(f.vocabulary(),
+ self.assertEqual(f.vocabulary(),
[(u'admin', u'admin'), (u'anon', u'anon')])
# ensure rqlst is left unmodified
- self.assertEquals(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
#rqlst = rset.syntax_tree()
- self.assertEquals(f.possible_values(),
+ self.assertEqual(f.possible_values(),
['admin', 'anon'])
# ensure rqlst is left unmodified
- self.assertEquals(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
req.form[f.__regid__] = 'admin'
f.add_rql_restrictions()
# selection is cluttered because rqlst has been prepared for facet (it
# is not in real life)
- self.assertEquals(f.rqlst.as_string(),
+ self.assertEqual(f.rqlst.as_string(),
"DISTINCT Any WHERE X is CWUser, X login 'admin'")
--- a/web/test/unittest_form.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_form.py Wed Sep 29 16:16:32 2010 +0200
@@ -36,10 +36,10 @@
def test_form_field_format(self):
form = FieldsForm(self.request(), None)
- self.assertEquals(StringField().format(form), 'text/html')
+ self.assertEqual(StringField().format(form), 'text/html')
self.execute('INSERT CWProperty X: X pkey "ui.default-text-format", X value "text/rest", X for_user U WHERE U login "admin"')
self.commit()
- self.assertEquals(StringField().format(form), 'text/rest')
+ self.assertEqual(StringField().format(form), 'text/rest')
class EntityFieldsFormTC(CubicWebTC):
@@ -70,7 +70,7 @@
form = self.vreg['forms'].select('edition', self.req, entity=e)
unrelated = [rview for rview, reid in form.field_by_name('in_group', 'subject').choices(form)]
# should be default groups but owners, i.e. managers, users, guests
- self.assertEquals(unrelated, [u'guests', u'managers', u'users'])
+ self.assertEqual(unrelated, [u'guests', u'managers', u'users'])
def test_consider_req_form_params(self):
e = self.vreg['etypes'].etype_class('CWUser')(self.request())
@@ -79,7 +79,7 @@
field = StringField(name='login', role='subject', eidparam=True)
form.append_field(field)
form.build_context({})
- self.assertEquals(field.widget.values(form, field), (u'toto',))
+ self.assertEqual(field.widget.values(form, field), (u'toto',))
def test_linkto_field_duplication(self):
@@ -144,7 +144,7 @@
form = RTFForm(self.req, redirect_path='perdu.com', entity=state)
# make it think it can use fck editor anyway
form.field_by_name('description', 'subject').format = lambda x: 'text/html'
- self.assertTextEquals(self._render_entity_field('description', form),
+ self.assertMultiLineEqual(self._render_entity_field('description', form),
expected % {'eid': state.eid})
@@ -174,7 +174,7 @@
file = self.req.create_entity('File', data_name=u"pouet.txt", data_encoding=u'UTF-8',
data=Binary('new widgets system'))
form = FFForm(self.req, redirect_path='perdu.com', entity=file)
- self.assertTextEquals(self._render_entity_field('data', form),
+ self.assertMultiLineEqual(self._render_entity_field('data', form),
'''<input id="data-subject:%(eid)s" name="data-subject:%(eid)s" tabindex="1" type="file" value="" />
<a href="javascript: toggleVisibility('data-subject:%(eid)s-advanced')" title="show advanced fields"><img src="http://testing.fr/cubicweb/data/puce_down.png" alt="show advanced fields"/></a>
<div id="data-subject:%(eid)s-advanced" class="hidden">
@@ -183,8 +183,7 @@
</div>
<br/>
<input name="data-subject__detach:%(eid)s" type="checkbox" />
-detach attached file
-''' % {'eid': file.eid})
+detach attached file''' % {'eid': file.eid})
def test_editablefilefield(self):
@@ -198,7 +197,7 @@
file = self.req.create_entity('File', data_name=u"pouet.txt", data_encoding=u'UTF-8',
data=Binary('new widgets system'))
form = EFFForm(self.req, redirect_path='perdu.com', entity=file)
- self.assertTextEquals(self._render_entity_field('data', form),
+ self.assertMultiLineEqual(self._render_entity_field('data', form),
'''<input id="data-subject:%(eid)s" name="data-subject:%(eid)s" tabindex="1" type="file" value="" />
<a href="javascript: toggleVisibility('data-subject:%(eid)s-advanced')" title="show advanced fields"><img src="http://testing.fr/cubicweb/data/puce_down.png" alt="show advanced fields"/></a>
<div id="data-subject:%(eid)s-advanced" class="hidden">
@@ -216,7 +215,7 @@
class PFForm(EntityFieldsForm):
upassword = PasswordField(eidparam=True, role='subject')
form = PFForm(self.req, redirect_path='perdu.com', entity=self.entity)
- self.assertTextEquals(self._render_entity_field('upassword', form),
+ self.assertMultiLineEqual(self._render_entity_field('upassword', form),
'''<input id="upassword-subject:%(eid)s" name="upassword-subject:%(eid)s" tabindex="1" type="password" value="" />
<br/>
<input name="upassword-subject-confirm:%(eid)s" tabindex="1" type="password" value="" />
@@ -230,7 +229,7 @@
# form = DFForm(self.req, entity=self.entity)
# init, cur = (fromstring(self._render_entity_field(attr, form)).get('value')
# for attr in ('edits-creation_date', 'creation_date'))
- # self.assertEquals(init, cur)
+ # self.assertEqual(init, cur)
if __name__ == '__main__':
unittest_main()
--- a/web/test/unittest_formfields.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_formfields.py Wed Sep 29 16:16:32 2010 +0200
@@ -38,64 +38,64 @@
def test_state_fields(self):
title_field = guess_field(schema['State'], schema['name'])
self.assertIsInstance(title_field, StringField)
- self.assertEquals(title_field.required, True)
+ self.assertEqual(title_field.required, True)
# synopsis_field = guess_field(schema['State'], schema['synopsis'])
# self.assertIsInstance(synopsis_field, StringField)
# self.assertIsInstance(synopsis_field.widget, TextArea)
-# self.assertEquals(synopsis_field.required, False)
-# self.assertEquals(synopsis_field.help, 'an abstract for this state')
+# self.assertEqual(synopsis_field.required, False)
+# self.assertEqual(synopsis_field.help, 'an abstract for this state')
description_field = guess_field(schema['State'], schema['description'])
self.assertIsInstance(description_field, RichTextField)
- self.assertEquals(description_field.required, False)
- self.assertEquals(description_field.format_field, None)
+ self.assertEqual(description_field.required, False)
+ self.assertEqual(description_field.format_field, None)
# description_format_field = guess_field(schema['State'], schema['description_format'])
- # self.assertEquals(description_format_field, None)
+ # self.assertEqual(description_format_field, None)
description_format_field = guess_field(schema['State'], schema['description_format'])
- self.assertEquals(description_format_field.internationalizable, True)
- self.assertEquals(description_format_field.sort, True)
+ self.assertEqual(description_format_field.internationalizable, True)
+ self.assertEqual(description_format_field.sort, True)
# wikiid_field = guess_field(schema['State'], schema['wikiid'])
# self.assertIsInstance(wikiid_field, StringField)
-# self.assertEquals(wikiid_field.required, False)
+# self.assertEqual(wikiid_field.required, False)
def test_cwuser_fields(self):
upassword_field = guess_field(schema['CWUser'], schema['upassword'])
self.assertIsInstance(upassword_field, StringField)
self.assertIsInstance(upassword_field.widget, PasswordInput)
- self.assertEquals(upassword_field.required, True)
+ self.assertEqual(upassword_field.required, True)
last_login_time_field = guess_field(schema['CWUser'], schema['last_login_time'])
self.assertIsInstance(last_login_time_field, DateTimeField)
- self.assertEquals(last_login_time_field.required, False)
+ self.assertEqual(last_login_time_field.required, False)
in_group_field = guess_field(schema['CWUser'], schema['in_group'])
self.assertIsInstance(in_group_field, RelationField)
- self.assertEquals(in_group_field.required, True)
- self.assertEquals(in_group_field.role, 'subject')
- self.assertEquals(in_group_field.help, 'groups grant permissions to the user')
+ self.assertEqual(in_group_field.required, True)
+ self.assertEqual(in_group_field.role, 'subject')
+ self.assertEqual(in_group_field.help, 'groups grant permissions to the user')
owned_by_field = guess_field(schema['CWUser'], schema['owned_by'], 'object')
self.assertIsInstance(owned_by_field, RelationField)
- self.assertEquals(owned_by_field.required, False)
- self.assertEquals(owned_by_field.role, 'object')
+ self.assertEqual(owned_by_field.required, False)
+ self.assertEqual(owned_by_field.role, 'object')
def test_file_fields(self):
# data_format_field = guess_field(schema['File'], schema['data_format'])
- # self.assertEquals(data_format_field, None)
+ # self.assertEqual(data_format_field, None)
# data_encoding_field = guess_field(schema['File'], schema['data_encoding'])
- # self.assertEquals(data_encoding_field, None)
+ # self.assertEqual(data_encoding_field, None)
# data_name_field = guess_field(schema['File'], schema['data_name'])
- # self.assertEquals(data_name_field, None)
+ # self.assertEqual(data_name_field, None)
data_field = guess_field(schema['File'], schema['data'])
self.assertIsInstance(data_field, FileField)
- self.assertEquals(data_field.required, True)
+ self.assertEqual(data_field.required, True)
self.assertIsInstance(data_field.format_field, StringField)
self.assertIsInstance(data_field.encoding_field, StringField)
self.assertIsInstance(data_field.name_field, StringField)
@@ -103,7 +103,7 @@
def test_constraints_priority(self):
salesterm_field = guess_field(schema['Salesterm'], schema['reason'])
constraints = schema['reason'].rdef('Salesterm', 'String').constraints
- self.assertEquals([c.__class__ for c in constraints],
+ self.assertEqual([c.__class__ for c in constraints],
[SizeConstraint, StaticVocabularyConstraint])
self.assertIsInstance(salesterm_field, StringField)
self.assertIsInstance(salesterm_field.widget, Select)
@@ -112,16 +112,16 @@
def test_bool_field_base(self):
field = guess_field(schema['CWAttribute'], schema['indexed'])
self.assertIsInstance(field, BooleanField)
- self.assertEquals(field.required, False)
+ self.assertEqual(field.required, False)
self.assertIsInstance(field.widget, Radio)
- self.assertEquals(field.vocabulary(mock(_cw=mock(_=unicode))),
+ self.assertEqual(field.vocabulary(mock(_cw=mock(_=unicode))),
[(u'yes', '1'), (u'no', '')])
def test_bool_field_explicit_choices(self):
field = guess_field(schema['CWAttribute'], schema['indexed'],
choices=[(u'maybe', '1'), (u'no', '')])
self.assertIsInstance(field.widget, Radio)
- self.assertEquals(field.vocabulary(mock(req=mock(_=unicode))),
+ self.assertEqual(field.vocabulary(mock(req=mock(_=unicode))),
[(u'maybe', '1'), (u'no', '')])
@@ -133,18 +133,18 @@
form = EntityFieldsForm(req, entity=e)
description_field = guess_field(schema['State'], schema['description'])
description_format_field = description_field.get_format_field(form)
- self.assertEquals(description_format_field.internationalizable, True)
- self.assertEquals(description_format_field.sort, True)
+ self.assertEqual(description_format_field.internationalizable, True)
+ self.assertEqual(description_format_field.sort, True)
# unlike below, initial is bound to form.form_field_format
- self.assertEquals(description_format_field.value(form), 'text/html')
+ self.assertEqual(description_format_field.value(form), 'text/html')
self.execute('INSERT CWProperty X: X pkey "ui.default-text-format", X value "text/rest", X for_user U WHERE U login "admin"')
self.commit()
- self.assertEquals(description_format_field.value(form), 'text/rest')
+ self.assertEqual(description_format_field.value(form), 'text/rest')
class UtilsTC(TestCase):
def test_vocab_sort(self):
- self.assertEquals(vocab_sort([('Z', 1), ('A', 2),
+ self.assertEqual(vocab_sort([('Z', 1), ('A', 2),
('Group 1', None), ('Y', 3), ('B', 4),
('Group 2', None), ('X', 5), ('C', 6)]),
[('A', 2), ('Z', 1),
--- a/web/test/unittest_magicsearch.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_magicsearch.py Wed Sep 29 16:16:32 2010 +0200
@@ -61,16 +61,16 @@
"""tests basic translations (no ambiguities)"""
rql = "Any C WHERE C is Adresse, P adel C, C adresse 'Logilab'"
rql, = self.proc.preprocess_query(rql)
- self.assertEquals(rql, "Any C WHERE C is EmailAddress, P use_email C, C address 'Logilab'")
+ self.assertEqual(rql, "Any C WHERE C is EmailAddress, P use_email C, C address 'Logilab'")
def test_ambiguous_translations(self):
"""tests possibly ambiguous translations"""
rql = "Any P WHERE P adel C, C is EmailAddress, C nom 'Logilab'"
rql, = self.proc.preprocess_query(rql)
- self.assertEquals(rql, "Any P WHERE P use_email C, C is EmailAddress, C alias 'Logilab'")
+ self.assertEqual(rql, "Any P WHERE P use_email C, C is EmailAddress, C alias 'Logilab'")
rql = "Any P WHERE P is Utilisateur, P adel C, P nom 'Smith'"
rql, = self.proc.preprocess_query(rql)
- self.assertEquals(rql, "Any P WHERE P is CWUser, P use_email C, P surname 'Smith'")
+ self.assertEqual(rql, "Any P WHERE P is CWUser, P use_email C, P surname 'Smith'")
class QSPreProcessorTC(CubicWebTC):
@@ -86,21 +86,21 @@
def test_entity_translation(self):
"""tests QSPreProcessor._get_entity_name()"""
translate = self.proc._get_entity_type
- self.assertEquals(translate(u'EmailAddress'), "EmailAddress")
- self.assertEquals(translate(u'emailaddress'), "EmailAddress")
- self.assertEquals(translate(u'Adresse'), "EmailAddress")
- self.assertEquals(translate(u'adresse'), "EmailAddress")
+ self.assertEqual(translate(u'EmailAddress'), "EmailAddress")
+ self.assertEqual(translate(u'emailaddress'), "EmailAddress")
+ self.assertEqual(translate(u'Adresse'), "EmailAddress")
+ self.assertEqual(translate(u'adresse'), "EmailAddress")
self.assertRaises(BadRQLQuery, translate, 'whatever')
def test_attribute_translation(self):
"""tests QSPreProcessor._get_attribute_name"""
translate = self.proc._get_attribute_name
eschema = self.schema.eschema('CWUser')
- self.assertEquals(translate(u'prénom', eschema), "firstname")
- self.assertEquals(translate(u'nom', eschema), 'surname')
+ self.assertEqual(translate(u'prénom', eschema), "firstname")
+ self.assertEqual(translate(u'nom', eschema), 'surname')
eschema = self.schema.eschema('EmailAddress')
- self.assertEquals(translate(u'adresse', eschema), "address")
- self.assertEquals(translate(u'nom', eschema), 'alias')
+ self.assertEqual(translate(u'adresse', eschema), "address")
+ self.assertEqual(translate(u'nom', eschema), 'alias')
# should fail if the name is not an attribute for the given entity schema
self.assertRaises(BadRQLQuery, translate, 'whatever', eschema)
self.assertRaises(BadRQLQuery, translate, 'prénom', eschema)
@@ -108,50 +108,50 @@
def test_one_word_query(self):
"""tests the 'one word shortcut queries'"""
transform = self.proc._one_word_query
- self.assertEquals(transform('123'),
+ self.assertEqual(transform('123'),
('Any X WHERE X eid %(x)s', {'x': 123}, 'x'))
- self.assertEquals(transform('CWUser'),
+ self.assertEqual(transform('CWUser'),
('CWUser C',))
- self.assertEquals(transform('Utilisateur'),
+ self.assertEqual(transform('Utilisateur'),
('CWUser C',))
- self.assertEquals(transform('Adresse'),
+ self.assertEqual(transform('Adresse'),
('EmailAddress E',))
- self.assertEquals(transform('adresse'),
+ self.assertEqual(transform('adresse'),
('EmailAddress E',))
self.assertRaises(BadRQLQuery, transform, 'Workcases')
def test_two_words_query(self):
"""tests the 'two words shortcut queries'"""
transform = self.proc._two_words_query
- self.assertEquals(transform('CWUser', 'E'),
+ self.assertEqual(transform('CWUser', 'E'),
("CWUser E",))
- self.assertEquals(transform('CWUser', 'Smith'),
+ self.assertEqual(transform('CWUser', 'Smith'),
('CWUser C ORDERBY FTIRANK(C) DESC WHERE C has_text %(text)s', {'text': 'Smith'}))
- self.assertEquals(transform('utilisateur', 'Smith'),
+ self.assertEqual(transform('utilisateur', 'Smith'),
('CWUser C ORDERBY FTIRANK(C) DESC WHERE C has_text %(text)s', {'text': 'Smith'}))
- self.assertEquals(transform(u'adresse', 'Logilab'),
+ self.assertEqual(transform(u'adresse', 'Logilab'),
('EmailAddress E ORDERBY FTIRANK(E) DESC WHERE E has_text %(text)s', {'text': 'Logilab'}))
- self.assertEquals(transform(u'adresse', 'Logi%'),
+ self.assertEqual(transform(u'adresse', 'Logi%'),
('EmailAddress E WHERE E alias LIKE %(text)s', {'text': 'Logi%'}))
self.assertRaises(BadRQLQuery, transform, "pers", "taratata")
def test_three_words_query(self):
"""tests the 'three words shortcut queries'"""
transform = self.proc._three_words_query
- self.assertEquals(transform('utilisateur', u'prénom', 'cubicweb'),
+ self.assertEqual(transform('utilisateur', u'prénom', 'cubicweb'),
('CWUser C WHERE C firstname %(text)s', {'text': 'cubicweb'}))
- self.assertEquals(transform('utilisateur', 'nom', 'cubicweb'),
+ self.assertEqual(transform('utilisateur', 'nom', 'cubicweb'),
('CWUser C WHERE C surname %(text)s', {'text': 'cubicweb'}))
- self.assertEquals(transform(u'adresse', 'nom', 'cubicweb'),
+ self.assertEqual(transform(u'adresse', 'nom', 'cubicweb'),
('EmailAddress E WHERE E alias %(text)s', {'text': 'cubicweb'}))
- self.assertEquals(transform('EmailAddress', 'nom', 'cubicweb'),
+ self.assertEqual(transform('EmailAddress', 'nom', 'cubicweb'),
('EmailAddress E WHERE E alias %(text)s', {'text': 'cubicweb'}))
- self.assertEquals(transform('utilisateur', u'prénom', 'cubicweb%'),
+ self.assertEqual(transform('utilisateur', u'prénom', 'cubicweb%'),
('CWUser C WHERE C firstname LIKE %(text)s', {'text': 'cubicweb%'}))
# expanded shortcuts
- self.assertEquals(transform('CWUser', 'use_email', 'Logilab'),
+ self.assertEqual(transform('CWUser', 'use_email', 'Logilab'),
('CWUser C ORDERBY FTIRANK(C1) DESC WHERE C use_email C1, C1 has_text %(text)s', {'text': 'Logilab'}))
- self.assertEquals(transform('CWUser', 'use_email', '%Logilab'),
+ self.assertEqual(transform('CWUser', 'use_email', '%Logilab'),
('CWUser C WHERE C use_email C1, C1 alias LIKE %(text)s', {'text': '%Logilab'}))
self.assertRaises(BadRQLQuery, transform, 'word1', 'word2', 'word3')
@@ -165,7 +165,7 @@
]
transform = self.proc._quoted_words_query
for query, expected in queries:
- self.assertEquals(transform(query), expected)
+ self.assertEqual(transform(query), expected)
self.assertRaises(BadRQLQuery, transform, "unquoted rql")
self.assertRaises(BadRQLQuery, transform, 'pers "Jean Paul"')
self.assertRaises(BadRQLQuery, transform, 'CWUser firstname other "Jean Paul"')
@@ -179,7 +179,7 @@
(u'CWUser prénom cubicweb', (u'CWUser C WHERE C firstname %(text)s', {'text': 'cubicweb'},)),
]
for query, expected in queries:
- self.assertEquals(self.proc.preprocess_query(query), expected)
+ self.assertEqual(self.proc.preprocess_query(query), expected)
self.assertRaises(BadRQLQuery,
self.proc.preprocess_query, 'Any X WHERE X is Something')
@@ -213,13 +213,13 @@
]
for query, expected in queries:
rset = self.proc.process_query(query)
- self.assertEquals((rset.rql, rset.args), expected)
+ self.assertEqual((rset.rql, rset.args), expected)
def test_accentuated_fulltext(self):
"""we must be able to type accentuated characters in the search field"""
rset = self.proc.process_query(u'écrire')
- self.assertEquals(rset.rql, "Any X ORDERBY FTIRANK(X) DESC WHERE X has_text %(text)s")
- self.assertEquals(rset.args, {'text': u'écrire'})
+ self.assertEqual(rset.rql, "Any X ORDERBY FTIRANK(X) DESC WHERE X has_text %(text)s")
+ self.assertEqual(rset.args, {'text': u'écrire'})
def test_explicit_component(self):
self.assertRaises(RQLSyntaxError,
@@ -227,8 +227,8 @@
self.assertRaises(BadRQLQuery,
self.proc.process_query, u'rql: CWUser E WHERE E noattr "Smith"')
rset = self.proc.process_query(u'text: utilisateur Smith')
- self.assertEquals(rset.rql, 'Any X ORDERBY FTIRANK(X) DESC WHERE X has_text %(text)s')
- self.assertEquals(rset.args, {'text': u'utilisateur Smith'})
+ self.assertEqual(rset.rql, 'Any X ORDERBY FTIRANK(X) DESC WHERE X has_text %(text)s')
+ self.assertEqual(rset.args, {'text': u'utilisateur Smith'})
if __name__ == '__main__':
unittest_main()
--- a/web/test/unittest_propertysheet.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_propertysheet.py Wed Sep 29 16:16:32 2010 +0200
@@ -19,21 +19,21 @@
ps.load(join(DATADIR, 'sheet1.py'))
ps.load(join(DATADIR, 'sheet2.py'))
# defined by sheet1
- self.assertEquals(ps['logo'], 'http://cwtest.com/logo.png')
+ self.assertEqual(ps['logo'], 'http://cwtest.com/logo.png')
# defined by sheet1, overriden by sheet2
- self.assertEquals(ps['bgcolor'], '#FFFFFF')
+ self.assertEqual(ps['bgcolor'], '#FFFFFF')
# defined by sheet2
- self.assertEquals(ps['fontcolor'], 'black')
+ self.assertEqual(ps['fontcolor'], 'black')
# defined by sheet1, extended by sheet2
- self.assertEquals(ps['stylesheets'], ['http://cwtest.com/cubicweb.css',
+ self.assertEqual(ps['stylesheets'], ['http://cwtest.com/cubicweb.css',
'http://cwtest.com/mycube.css'])
# lazy string defined by sheet1
self.assertIsInstance(ps['lazy'], lazystr)
- self.assertEquals(str(ps['lazy']), '#FFFFFF')
+ self.assertEqual(str(ps['lazy']), '#FFFFFF')
# test compilation
- self.assertEquals(ps.compile('a {bgcolor: %(bgcolor)s; size: 1%;}'),
+ self.assertEqual(ps.compile('a {bgcolor: %(bgcolor)s; size: 1%;}'),
'a {bgcolor: #FFFFFF; size: 1%;}')
- self.assertEquals(ps.process_resource(DATADIR, 'pouet.css'),
+ self.assertEqual(ps.process_resource(DATADIR, 'pouet.css'),
CACHEDIR)
self.failUnless('pouet.css' in ps._cache)
self.failIf(ps.need_reload())
--- a/web/test/unittest_reledit.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_reledit.py Wed Sep 29 16:16:32 2010 +0200
@@ -43,7 +43,7 @@
if rschema not in reledit:
continue
rtype = rschema.type
- self.assertTextEquals(reledit[rtype] % {'eid': self.proj.eid}, self.proj.view('reledit', rtype=rtype, role=role), rtype)
+ self.assertMultiLineEqual(reledit[rtype] % {'eid': self.proj.eid}, self.proj.view('reledit', rtype=rtype, role=role), rtype)
def test_default_forms(self):
doreledit = {'title': """<div id="title-subject-%(eid)s-reledit" onmouseout="jQuery('#title-subject-%(eid)s').addClass('hidden')" onmouseover="jQuery('#title-subject-%(eid)s').removeClass('hidden')" class="releditField"><div id="title-subject-%(eid)s-value" class="editableFieldValue">cubicweb-world-domination</div><form action="http://testing.fr/cubicweb/validateform?__onsuccess=window.parent.cw.reledit.onSuccess" method="post" enctype="application/x-www-form-urlencoded" id="title-subject-%(eid)s-form" onsubmit="return freezeFormButtons('title-subject-%(eid)s-form');" class="releditForm" cubicweb:target="eformframe">
@@ -177,7 +177,7 @@
if rschema not in doreledit:
continue
rtype = rschema.type
- self.assertTextEquals(doreledit[rtype] % {'eid': self.proj.eid, 'toto': self.toto.eid},
+ self.assertMultiLineEqual(doreledit[rtype] % {'eid': self.proj.eid, 'toto': self.toto.eid},
self.proj.view('doreledit', rtype=rtype, role=role,
formid='edition' if rtype == 'long_desc' else 'base'),
rtype)
@@ -213,7 +213,7 @@
if rschema not in reledit:
continue
rtype = rschema.type
- self.assertTextEquals(reledit[rtype] % {'eid': self.proj.eid, 'toto': self.toto.eid, 'tick': self.tick.eid},
+ self.assertMultiLineEqual(reledit[rtype] % {'eid': self.proj.eid, 'toto': self.toto.eid, 'tick': self.tick.eid},
self.proj.view('reledit', rtype=rtype, role=role),
rtype)
reledit_ctrl.clear()
--- a/web/test/unittest_session.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_session.py Wed Sep 29 16:16:32 2010 +0200
@@ -16,16 +16,24 @@
# make is if the web session has been opened by the session manager
sm._sessions[self.cnx.sessionid] = self.websession
sessionid = self.websession.sessionid
- self.assertEquals(len(sm._sessions), 1)
- self.assertEquals(self.websession.sessionid, self.websession.cnx.sessionid)
+ self.assertEqual(len(sm._sessions), 1)
+ self.assertEqual(self.websession.sessionid, self.websession.cnx.sessionid)
# fake the repo session is expiring
self.repo.close(sessionid)
try:
# fake an incoming http query with sessionid in session cookie
# don't use self.request() which try to call req.set_session
req = self.requestcls(self.vreg)
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/web/test/unittest_session.py
self.assertRaises(InvalidSession, sm.get_session, req, sessionid)
self.assertEquals(len(sm._sessions), 0)
+=======
+ websession = sm.get_session(req, sessionid)
+ self.assertEqual(len(sm._sessions), 1)
+ self.assertIs(websession, self.websession)
+ self.assertEqual(websession.sessionid, sessionid)
+ self.assertNotEquals(websession.sessionid, websession.cnx.sessionid)
+>>>>>>> /tmp/unittest_session.py~other.sGNH8u
finally:
# avoid error in tearDown by telling this connection is closed...
self.cnx._closed = True
--- a/web/test/unittest_uicfg.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_uicfg.py Wed Sep 29 16:16:32 2010 +0200
@@ -62,7 +62,7 @@
def test_definition_order_hidden(self):
result = uicfg.autoform_section.get('CWUser', 'login', 'String', 'subject')
expected = set(['main_inlined', 'muledit_attributes', 'inlined_attributes'])
- self.assertSetEquals(result, expected)
+ self.assertSetEqual(result, expected)
def tearDown(self):
super(DefinitionOrderTC, self).tearDown()
--- a/web/test/unittest_urlpublisher.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_urlpublisher.py Wed Sep 29 16:16:32 2010 +0200
@@ -45,51 +45,51 @@
def test_raw_path(self):
"""tests raw path resolution'"""
- self.assertEquals(self.process('view'), ('view', None))
- self.assertEquals(self.process('edit'), ('edit', None))
+ self.assertEqual(self.process('view'), ('view', None))
+ self.assertEqual(self.process('edit'), ('edit', None))
self.assertRaises(NotFound, self.process, 'whatever')
def test_eid_path(self):
"""tests eid path resolution"""
self.assertIsInstance(self.process('123')[1], ResultSet)
- self.assertEquals(len(self.process('123')[1]), 1)
+ self.assertEqual(len(self.process('123')[1]), 1)
self.assertRaises(NotFound, self.process, '123/345')
self.assertRaises(NotFound, self.process, 'not_eid')
def test_rest_path(self):
"""tests the rest path resolution"""
ctrl, rset = self.process('CWUser')
- self.assertEquals(ctrl, 'view')
- self.assertEquals(rset.description[0][0], 'CWUser')
- self.assertEquals(rset.printable_rql(),
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(rset.description[0][0], 'CWUser')
+ self.assertEqual(rset.printable_rql(),
"Any X,AA,AB,AC,AD ORDERBY AA WHERE X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD")
ctrl, rset = self.process('CWUser/login/admin')
- self.assertEquals(ctrl, 'view')
- self.assertEquals(len(rset), 1)
- self.assertEquals(rset.description[0][0], 'CWUser')
- self.assertEquals(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X login "admin", X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD')
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.description[0][0], 'CWUser')
+ self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X login "admin", X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD')
ctrl, rset = self.process('cwuser/admin')
- self.assertEquals(ctrl, 'view')
- self.assertEquals(len(rset), 1)
- self.assertEquals(rset.description[0][0], 'CWUser')
- self.assertEquals(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X login "admin", X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD')
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.description[0][0], 'CWUser')
+ self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X login "admin", X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD')
ctrl, rset = self.process('cwuser/eid/%s'%rset[0][0])
- self.assertEquals(ctrl, 'view')
- self.assertEquals(len(rset), 1)
- self.assertEquals(rset.description[0][0], 'CWUser')
- self.assertEquals(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X eid 5, X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD')
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.description[0][0], 'CWUser')
+ self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X eid 5, X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD')
# test non-ascii paths
ctrl, rset = self.process('CWUser/login/%C3%BFsa%C3%BFe')
- self.assertEquals(ctrl, 'view')
- self.assertEquals(len(rset), 1)
- self.assertEquals(rset.description[0][0], 'CWUser')
- self.assertEquals(rset.printable_rql(), u'Any X,AA,AB,AC,AD WHERE X login "\xffsa\xffe", X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD')
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.description[0][0], 'CWUser')
+ self.assertEqual(rset.printable_rql(), u'Any X,AA,AB,AC,AD WHERE X login "\xffsa\xffe", X is CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD')
# test quoted paths
ctrl, rset = self.process('BlogEntry/title/hell%27o')
- self.assertEquals(ctrl, 'view')
- self.assertEquals(len(rset), 1)
- self.assertEquals(rset.description[0][0], 'BlogEntry')
- self.assertEquals(rset.printable_rql(), u'Any X,AA,AB,AC WHERE X title "hell\'o", X is BlogEntry, X creation_date AA, X title AB, X modification_date AC')
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.description[0][0], 'BlogEntry')
+ self.assertEqual(rset.printable_rql(), u'Any X,AA,AB,AC WHERE X title "hell\'o", X is BlogEntry, X creation_date AA, X title AB, X modification_date AC')
# errors
self.assertRaises(NotFound, self.process, 'CWUser/eid/30000')
self.assertRaises(NotFound, self.process, 'Workcases')
@@ -108,9 +108,9 @@
def test_regexp_path(self):
"""tests the regexp path resolution"""
ctrl, rset = self.process('add/Task')
- self.assertEquals(ctrl, 'view')
- self.assertEquals(rset, None)
- self.assertEquals(self.req.form, {'etype' : "Task", 'vid' : "creation"})
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(rset, None)
+ self.assertEqual(self.req.form, {'etype' : "Task", 'vid' : "creation"})
self.assertRaises(NotFound, self.process, 'add/foo/bar')
@@ -120,8 +120,8 @@
try:
path = str(FakeRequest().url_quote(u'été'))
ctrl, rset = self.process(path)
- self.assertEquals(rset, None)
- self.assertEquals(self.req.form, {'vid' : "foo"})
+ self.assertEqual(rset, None)
+ self.assertEqual(self.req.form, {'vid' : "foo"})
finally:
SimpleReqRewriter.rules = oldrules
--- a/web/test/unittest_urlrewrite.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_urlrewrite.py Wed Sep 29 16:16:32 2010 +0200
@@ -39,7 +39,7 @@
if hasattr(pattern, 'pattern'):
pattern = pattern.pattern
rules.append((pattern, values))
- self.assertListEquals(rules, [
+ self.assertListEqual(rules, [
('foo' , dict(rql='Foo F')),
('/index' , dict(vid='index2')),
('/_', dict(vid='manage')),
@@ -71,7 +71,7 @@
('foo', dict(rql='Foo F')),
('/index', dict(vid='index2')),
]
- self.assertListEquals(Rewriter.rules, [
+ self.assertListEqual(Rewriter.rules, [
('foo' , dict(rql='Foo F')),
('/index' , dict(vid='index2')),
])
@@ -81,19 +81,19 @@
req = FakeRequest()
rewriter = SimpleReqRewriter(req)
self.assertRaises(KeyError, rewriter.rewrite, req, '/view?vid=whatever')
- self.assertEquals(req.form, {})
+ self.assertEqual(req.form, {})
rewriter.rewrite(req, '/index')
- self.assertEquals(req.form, {'vid' : "index"})
+ self.assertEqual(req.form, {'vid' : "index"})
def test_regexp_transformation(self):
"""test regexp-based rewrite"""
req = FakeRequest()
rewriter = SimpleReqRewriter(req)
rewriter.rewrite(req, '/add/Task')
- self.assertEquals(req.form, {'vid' : "creation", 'etype' : "Task"})
+ self.assertEqual(req.form, {'vid' : "creation", 'etype' : "Task"})
req = FakeRequest()
rewriter.rewrite(req, '/add/Task/')
- self.assertEquals(req.form, {'vid' : "creation", 'etype' : "Task"})
+ self.assertEqual(req.form, {'vid' : "creation", 'etype' : "Task"})
@@ -117,8 +117,8 @@
req = self.request()
rewriter = TestSchemaBasedRewriter(req)
pmid, rset = rewriter.rewrite(req, u'/DaLToN/JoE')
- self.assertEquals(len(rset), 1)
- self.assertEquals(rset[0][0], self.p1.eid)
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset[0][0], self.p1.eid)
def test_inheritance_precedence(self):
RQL1 = 'Any C WHERE C is CWEType'
@@ -142,17 +142,17 @@
req = self.request()
rewriter = Rewriter(req)
pmid, rset = rewriter.rewrite(req, '/collector')
- self.assertEquals(rset.rql, RQL1)
- self.assertEquals(req.form, {'vid' : "baseindex"})
+ self.assertEqual(rset.rql, RQL1)
+ self.assertEqual(req.form, {'vid' : "baseindex"})
pmid, rset = rewriter.rewrite(req, '/collector/something')
- self.assertEquals(rset.rql, RQL2)
- self.assertEquals(req.form, {'vid' : "index"})
+ self.assertEqual(rset.rql, RQL2)
+ self.assertEqual(req.form, {'vid' : "index"})
pmid, rset = rewriter.rewrite(req, '/collector/something/')
- self.assertEquals(req.form, {'vid' : "index"})
- self.assertEquals(rset.rql, RQL2)
+ self.assertEqual(req.form, {'vid' : "index"})
+ self.assertEqual(rset.rql, RQL2)
pmid, rset = rewriter.rewrite(req, '/collector/somethingelse/')
- self.assertEquals(rset.rql, RQL1)
- self.assertEquals(req.form, {'vid' : "baseindex"})
+ self.assertEqual(rset.rql, RQL1)
+ self.assertEqual(req.form, {'vid' : "baseindex"})
def test_inheritance_precedence_same_rgx(self):
RQL1 = 'Any C WHERE C is CWEType'
@@ -176,17 +176,17 @@
req = self.request()
rewriter = Rewriter(req)
pmid, rset = rewriter.rewrite(req, '/collector')
- self.assertEquals(rset.rql, RQL2)
- self.assertEquals(req.form, {'vid' : "index"})
+ self.assertEqual(rset.rql, RQL2)
+ self.assertEqual(req.form, {'vid' : "index"})
pmid, rset = rewriter.rewrite(req, '/collector/something')
- self.assertEquals(rset.rql, RQL2)
- self.assertEquals(req.form, {'vid' : "index"})
+ self.assertEqual(rset.rql, RQL2)
+ self.assertEqual(req.form, {'vid' : "index"})
pmid, rset = rewriter.rewrite(req, '/collector/something/')
- self.assertEquals(req.form, {'vid' : "index"})
- self.assertEquals(rset.rql, RQL2)
+ self.assertEqual(req.form, {'vid' : "index"})
+ self.assertEqual(rset.rql, RQL2)
pmid, rset = rewriter.rewrite(req, '/collector/somethingelse/')
- self.assertEquals(rset.rql, RQL2)
- self.assertEquals(req.form, {'vid' : "index"})
+ self.assertEqual(rset.rql, RQL2)
+ self.assertEqual(req.form, {'vid' : "index"})
if __name__ == '__main__':
--- a/web/test/unittest_views_actions.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_views_actions.py Wed Sep 29 16:16:32 2010 +0200
@@ -28,7 +28,7 @@
rset = self.execute('CWUser X')
actions = self.vreg['actions'].poss_visible_objects(req, rset=rset)
vaction = [action for action in actions if action.__regid__ == 'view'][0]
- self.assertEquals(vaction.url(), 'http://testing.fr/cubicweb/view?rql=CWUser%20X')
+ self.assertEqual(vaction.url(), 'http://testing.fr/cubicweb/view?rql=CWUser%20X')
def test_sendmail_action(self):
req = self.request()
--- a/web/test/unittest_views_apacherewrite.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_views_apacherewrite.py Wed Sep 29 16:16:32 2010 +0200
@@ -41,18 +41,18 @@
urlrewriter.rewrite('logilab.fr', '/whatever', req)
self.fail('redirect exception expected')
except Redirect, ex:
- self.assertEquals(ex.location, 'http://www.logilab.fr/whatever')
- self.assertEquals(urlrewriter.rewrite('www.logilab.fr', '/whatever', req),
+ self.assertEqual(ex.location, 'http://www.logilab.fr/whatever')
+ self.assertEqual(urlrewriter.rewrite('www.logilab.fr', '/whatever', req),
'/whatever')
- self.assertEquals(urlrewriter.rewrite('www.logilab.fr', '/json/bla', req),
+ self.assertEqual(urlrewriter.rewrite('www.logilab.fr', '/json/bla', req),
'/json/bla')
- self.assertEquals(urlrewriter.rewrite('abcd.logilab.fr', '/json/bla', req),
+ self.assertEqual(urlrewriter.rewrite('abcd.logilab.fr', '/json/bla', req),
'/json/bla')
- self.assertEquals(urlrewriter.rewrite('abcd.logilab.fr', '/data/bla', req),
+ self.assertEqual(urlrewriter.rewrite('abcd.logilab.fr', '/data/bla', req),
'/data/bla')
- self.assertEquals(urlrewriter.rewrite('abcd.logilab.fr', '/whatever', req),
+ self.assertEqual(urlrewriter.rewrite('abcd.logilab.fr', '/whatever', req),
'/m_abcd/whatever')
- self.assertEquals(urlrewriter.rewrite('abcd.fr', '/whatever', req),
+ self.assertEqual(urlrewriter.rewrite('abcd.fr', '/whatever', req),
'/whatever')
--- a/web/test/unittest_views_basecontrollers.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_views_basecontrollers.py Wed Sep 29 16:16:32 2010 +0200
@@ -48,7 +48,7 @@
"""check behaviour of this controller without any form parameter
"""
ex = self.assertRaises(ValidationError, self.ctrl_publish, self.request())
- self.assertEquals(ex.errors, {None: u'no selected entities'})
+ self.assertEqual(ex.errors, {None: u'no selected entities'})
def test_validation_unique(self):
"""test creation of two linked entities
@@ -62,7 +62,7 @@
'upassword-subject-confirm:X': u'toto',
}
ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
- self.assertEquals(ex.errors, {'login-subject': 'the value "admin" is already used, use another one'})
+ self.assertEqual(ex.errors, {'login-subject': 'the value "admin" is already used, use another one'})
def test_user_editing_itself(self):
"""checking that a manager user can edit itself
@@ -83,10 +83,10 @@
}
path, params = self.expect_redirect_publish(req, 'edit')
e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
- self.assertEquals(e.firstname, u'Sylvain')
- self.assertEquals(e.surname, u'Th\xe9nault')
- self.assertEquals(e.login, user.login)
- self.assertEquals([g.eid for g in e.in_group], groupeids)
+ self.assertEqual(e.firstname, u'Sylvain')
+ self.assertEqual(e.surname, u'Th\xe9nault')
+ self.assertEqual(e.login, user.login)
+ self.assertEqual([g.eid for g in e.in_group], groupeids)
def test_user_can_change_its_password(self):
user = self.create_user('user')
@@ -102,7 +102,7 @@
}
path, params = self.expect_redirect_publish(req, 'edit')
cnx.commit() # commit to check we don't get late validation error for instance
- self.assertEquals(path, 'cwuser/user')
+ self.assertEqual(path, 'cwuser/user')
self.failIf('vid' in params)
def test_user_editing_itself_no_relation(self):
@@ -123,11 +123,11 @@
}
path, params = self.expect_redirect_publish(req, 'edit')
e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
- self.assertEquals(e.login, user.login)
- self.assertEquals(e.firstname, u'Th\xe9nault')
- self.assertEquals(e.surname, u'Sylvain')
- self.assertEquals([g.eid for g in e.in_group], groupeids)
- self.assertEquals(e.cw_adapt_to('IWorkflowable').state, 'activated')
+ self.assertEqual(e.login, user.login)
+ self.assertEqual(e.firstname, u'Th\xe9nault')
+ self.assertEqual(e.surname, u'Sylvain')
+ self.assertEqual([g.eid for g in e.in_group], groupeids)
+ self.assertEqual(e.cw_adapt_to('IWorkflowable').state, 'activated')
def test_create_multiple_linked(self):
@@ -149,11 +149,11 @@
}
path, params = self.expect_redirect_publish(req, 'edit')
# should be redirected on the created person
- self.assertEquals(path, 'cwuser/adim')
+ self.assertEqual(path, 'cwuser/adim')
e = self.execute('Any P WHERE P surname "Di Mascio"').get_entity(0, 0)
- self.assertEquals(e.surname, 'Di Mascio')
+ self.assertEqual(e.surname, 'Di Mascio')
email = e.use_email[0]
- self.assertEquals(email.address, 'dima@logilab.fr')
+ self.assertEqual(email.address, 'dima@logilab.fr')
def test_edit_multiple_linked(self):
peid = u(self.create_user('adim').eid)
@@ -171,10 +171,10 @@
}
path, params = self.expect_redirect_publish(req, 'edit')
# should be redirected on the created person
- self.assertEquals(path, 'cwuser/adim')
+ self.assertEqual(path, 'cwuser/adim')
e = self.execute('Any P WHERE P surname "Di Masci"').get_entity(0, 0)
email = e.use_email[0]
- self.assertEquals(email.address, 'dima@logilab.fr')
+ self.assertEqual(email.address, 'dima@logilab.fr')
emaileid = u(email.eid)
req = self.request()
@@ -191,7 +191,7 @@
}
path, params = self.expect_redirect_publish(req, 'edit')
email.clear_all_caches()
- self.assertEquals(email.address, 'adim@logilab.fr')
+ self.assertEqual(email.address, 'adim@logilab.fr')
def test_password_confirm(self):
@@ -206,7 +206,7 @@
'upassword-subject:X': u'toto',
}
ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
- self.assertEquals(ex.errors, {'upassword-subject': u'password and confirmation don\'t match'})
+ self.assertEqual(ex.errors, {'upassword-subject': u'password and confirmation don\'t match'})
req = self.request()
req.form = {'__cloned_eid:X': u(user.eid),
'eid': 'X', '__type:X': 'CWUser',
@@ -216,12 +216,13 @@
'upassword-subject-confirm:X': u'tutu',
}
ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
- self.assertEquals(ex.errors, {'upassword-subject': u'password and confirmation don\'t match'})
+ self.assertEqual(ex.errors, {'upassword-subject': u'password and confirmation don\'t match'})
def test_interval_bound_constraint_success(self):
feid = self.execute('INSERT File X: X data_name "toto.txt", X data %(data)s',
{'data': Binary('yo')})[0][0]
+ self.commit()
req = self.request()
req.form = {'eid': ['X'],
'__type:X': 'Salesterm',
@@ -230,7 +231,7 @@
'described_by_test-subject:X': u(feid),
}
ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
- self.assertEquals(ex.errors, {'amount-subject': 'value must be >= 0'})
+ self.assertEqual(ex.errors, {'amount-subject': 'value must be >= 0'})
req = self.request()
req.form = {'eid': ['X'],
'__type:X': 'Salesterm',
@@ -239,7 +240,7 @@
'described_by_test-subject:X': u(feid),
}
ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
- self.assertEquals(ex.errors, {'amount-subject': 'value must be <= 100'})
+ self.assertEqual(ex.errors, {'amount-subject': 'value must be <= 100'})
req = self.request()
req.form = {'eid': ['X'],
'__type:X': 'Salesterm',
@@ -251,7 +252,7 @@
# should be redirected on the created
#eid = params['rql'].split()[-1]
e = self.execute('Salesterm X').get_entity(0, 0)
- self.assertEquals(e.amount, 10)
+ self.assertEqual(e.amount, 10)
def test_req_pending_insert(self):
"""make sure req's pending insertions are taken into account"""
@@ -262,8 +263,8 @@
path, params = self.expect_redirect_publish(req, 'edit')
usergroups = [gname for gname, in
self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
- self.assertUnorderedIterableEquals(usergroups, ['managers', 'test'])
- self.assertEquals(get_pending_inserts(req), [])
+ self.assertItemsEqual(usergroups, ['managers', 'test'])
+ self.assertEqual(get_pending_inserts(req), [])
def test_req_pending_delete(self):
@@ -274,15 +275,15 @@
usergroups = [gname for gname, in
self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
# just make sure everything was set correctly
- self.assertUnorderedIterableEquals(usergroups, ['managers', 'test'])
+ self.assertItemsEqual(usergroups, ['managers', 'test'])
# now try to delete the relation
req = self.request(**req_form(user))
req.session.data['pending_delete'] = set([(user.eid, 'in_group', groupeid)])
path, params = self.expect_redirect_publish(req, 'edit')
usergroups = [gname for gname, in
self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
- self.assertUnorderedIterableEquals(usergroups, ['managers'])
- self.assertEquals(get_pending_deletes(req), [])
+ self.assertItemsEqual(usergroups, ['managers'])
+ self.assertEqual(get_pending_deletes(req), [])
# def test_custom_attribute_handler(self):
# def custom_login_edit(self, formparams, value, relations):
@@ -300,7 +301,7 @@
# }
# path, params = self.expect_redirect_publish(req, 'edit')
# rset = self.execute('Any L WHERE X eid %(x)s, X login L', {'x': user.eid}, 'x')
- # self.assertEquals(rset[0][0], 'FOO')
+ # self.assertEqual(rset[0][0], 'FOO')
# finally:
# del CWUser.custom_login_edit
@@ -321,11 +322,11 @@
path, params = self.expect_redirect_publish(req, 'edit')
self.failUnless(path.startswith('blogentry/'))
eid = path.split('/')[1]
- self.assertEquals(params['vid'], 'edition')
+ self.assertEqual(params['vid'], 'edition')
self.assertNotEquals(int(eid), 4012)
- self.assertEquals(params['__redirectrql'], redirectrql)
- self.assertEquals(params['__redirectvid'], 'primary')
- self.assertEquals(params['__redirectparams'], 'toto=tutu&tata=titi')
+ self.assertEqual(params['__redirectrql'], redirectrql)
+ self.assertEqual(params['__redirectvid'], 'primary')
+ self.assertEqual(params['__redirectparams'], 'toto=tutu&tata=titi')
def test_redirect_ok_button(self):
redirectrql = rql_for_eid(4012) # whatever
@@ -341,11 +342,11 @@
'__form_id': 'edition',
}
path, params = self.expect_redirect_publish(req, 'edit')
- self.assertEquals(path, 'view')
- self.assertEquals(params['rql'], redirectrql)
- self.assertEquals(params['vid'], 'primary')
- self.assertEquals(params['tata'], 'titi')
- self.assertEquals(params['toto'], 'tutu')
+ self.assertEqual(path, 'view')
+ self.assertEqual(params['rql'], redirectrql)
+ self.assertEqual(params['vid'], 'primary')
+ self.assertEqual(params['tata'], 'titi')
+ self.assertEqual(params['toto'], 'tutu')
def test_redirect_delete_button(self):
req = self.request()
@@ -353,7 +354,7 @@
req.form = {'eid': u(eid), '__type:%s'%eid: 'BlogEntry',
'__action_delete': ''}
path, params = self.expect_redirect_publish(req, 'edit')
- self.assertEquals(path, 'blogentry')
+ self.assertEqual(path, 'blogentry')
self.assertIn('_cwmsgid', params)
eid = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
self.execute('SET X use_email E WHERE E eid %(e)s, X eid %(x)s',
@@ -363,7 +364,7 @@
req.form = {'eid': u(eid), '__type:%s'%eid: 'EmailAddress',
'__action_delete': ''}
path, params = self.expect_redirect_publish(req, 'edit')
- self.assertEquals(path, 'cwuser/admin')
+ self.assertEqual(path, 'cwuser/admin')
self.assertIn('_cwmsgid', params)
eid1 = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
eid2 = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
@@ -373,7 +374,7 @@
'__type:%s'%eid2: 'EmailAddress',
'__action_delete': ''}
path, params = self.expect_redirect_publish(req, 'edit')
- self.assertEquals(path, 'view')
+ self.assertEqual(path, 'view')
self.assertIn('_cwmsgid', params)
def test_nonregr_eetype_etype_editing(self):
@@ -397,8 +398,8 @@
try:
path, params = self.expect_redirect_publish(req, 'edit')
e = self.execute('Any X WHERE X eid %(x)s', {'x': cwetypeeid}).get_entity(0, 0)
- self.assertEquals(e.name, 'CWEType')
- self.assertEquals(sorted(g.eid for g in e.read_permission), groupeids)
+ self.assertEqual(e.name, 'CWEType')
+ self.assertEqual(sorted(g.eid for g in e.read_permission), groupeids)
finally:
# restore
self.execute('SET X read_permission Y WHERE X name "CWEType", Y eid IN (%s), NOT X read_permission Y' % (','.join(basegroups)))
@@ -419,8 +420,8 @@
self.failUnless(path.startswith('blogentry/'))
eid = path.split('/')[1]
e = self.execute('Any C, T WHERE C eid %(x)s, C content T', {'x': eid}).get_entity(0, 0)
- self.assertEquals(e.title, '"13:03:40"')
- self.assertEquals(e.content, '"13:03:43"')
+ self.assertEqual(e.title, '"13:03:40"')
+ self.assertEqual(e.content, '"13:03:43"')
def test_nonregr_multiple_empty_email_addr(self):
@@ -441,7 +442,7 @@
'use_email-object:Y': 'X',
}
ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
- self.assertEquals(ex.errors, {'address-subject': u'required field'})
+ self.assertEqual(ex.errors, {'address-subject': u'required field'})
def test_nonregr_copy(self):
user = self.user()
@@ -453,10 +454,10 @@
'upassword-subject:X': u'toto', 'upassword-subject-confirm:X': u'toto',
}
path, params = self.expect_redirect_publish(req, 'edit')
- self.assertEquals(path, 'cwuser/toto')
+ self.assertEqual(path, 'cwuser/toto')
e = self.execute('Any X WHERE X is CWUser, X login "toto"').get_entity(0, 0)
- self.assertEquals(e.login, 'toto')
- self.assertEquals(e.in_group[0].name, 'managers')
+ self.assertEqual(e.login, 'toto')
+ self.assertEqual(e.in_group[0].name, 'managers')
def test_nonregr_rollback_on_validation_error(self):
@@ -488,7 +489,7 @@
req.form['vid'] = 'copy'
self.app_publish(req, 'view')
rset = self.execute('CWUser P WHERE P surname "Boom"')
- self.assertEquals(len(rset), 0)
+ self.assertEqual(len(rset), 0)
finally:
p.__class__.skip_copy_for = old_skips
@@ -560,95 +561,95 @@
# def test_json_exec(self):
# rql = 'Any T,N WHERE T is Tag, T name N'
# ctrl = self.ctrl(self.request(mode='json', rql=rql, pageid='123'))
-# self.assertEquals(ctrl.publish(),
+# self.assertEqual(ctrl.publish(),
# json_dumps(self.execute(rql).rows))
def test_remote_add_existing_tag(self):
self.remote_call('tag_entity', self.john.eid, ['python'])
- self.assertUnorderedIterableEquals(
+ self.assertItemsEqual(
[tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
['python', 'cubicweb'])
- self.assertEquals(
+ self.assertEqual(
self.execute('Any N WHERE T tags P, P is CWUser, T name N').rows,
[['python']])
def test_remote_add_new_tag(self):
self.remote_call('tag_entity', self.john.eid, ['javascript'])
- self.assertUnorderedIterableEquals(
+ self.assertItemsEqual(
[tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
['python', 'cubicweb', 'javascript'])
- self.assertEquals(
+ self.assertEqual(
self.execute('Any N WHERE T tags P, P is CWUser, T name N').rows,
[['javascript']])
def test_pending_insertion(self):
res, req = self.remote_call('add_pending_inserts', [['12', 'tags', '13']])
deletes = get_pending_deletes(req)
- self.assertEquals(deletes, [])
+ self.assertEqual(deletes, [])
inserts = get_pending_inserts(req)
- self.assertEquals(inserts, ['12:tags:13'])
+ self.assertEqual(inserts, ['12:tags:13'])
res, req = self.remote_call('add_pending_inserts', [['12', 'tags', '14']])
deletes = get_pending_deletes(req)
- self.assertEquals(deletes, [])
+ self.assertEqual(deletes, [])
inserts = get_pending_inserts(req)
- self.assertEquals(inserts, ['12:tags:13', '12:tags:14'])
+ self.assertEqual(inserts, ['12:tags:13', '12:tags:14'])
inserts = get_pending_inserts(req, 12)
- self.assertEquals(inserts, ['12:tags:13', '12:tags:14'])
+ self.assertEqual(inserts, ['12:tags:13', '12:tags:14'])
inserts = get_pending_inserts(req, 13)
- self.assertEquals(inserts, ['12:tags:13'])
+ self.assertEqual(inserts, ['12:tags:13'])
inserts = get_pending_inserts(req, 14)
- self.assertEquals(inserts, ['12:tags:14'])
+ self.assertEqual(inserts, ['12:tags:14'])
req.remove_pending_operations()
def test_pending_deletion(self):
res, req = self.remote_call('add_pending_delete', ['12', 'tags', '13'])
inserts = get_pending_inserts(req)
- self.assertEquals(inserts, [])
+ self.assertEqual(inserts, [])
deletes = get_pending_deletes(req)
- self.assertEquals(deletes, ['12:tags:13'])
+ self.assertEqual(deletes, ['12:tags:13'])
res, req = self.remote_call('add_pending_delete', ['12', 'tags', '14'])
inserts = get_pending_inserts(req)
- self.assertEquals(inserts, [])
+ self.assertEqual(inserts, [])
deletes = get_pending_deletes(req)
- self.assertEquals(deletes, ['12:tags:13', '12:tags:14'])
+ self.assertEqual(deletes, ['12:tags:13', '12:tags:14'])
deletes = get_pending_deletes(req, 12)
- self.assertEquals(deletes, ['12:tags:13', '12:tags:14'])
+ self.assertEqual(deletes, ['12:tags:13', '12:tags:14'])
deletes = get_pending_deletes(req, 13)
- self.assertEquals(deletes, ['12:tags:13'])
+ self.assertEqual(deletes, ['12:tags:13'])
deletes = get_pending_deletes(req, 14)
- self.assertEquals(deletes, ['12:tags:14'])
+ self.assertEqual(deletes, ['12:tags:14'])
req.remove_pending_operations()
def test_remove_pending_operations(self):
self.remote_call('add_pending_delete', ['12', 'tags', '13'])
_, req = self.remote_call('add_pending_inserts', [['12', 'tags', '14']])
inserts = get_pending_inserts(req)
- self.assertEquals(inserts, ['12:tags:14'])
+ self.assertEqual(inserts, ['12:tags:14'])
deletes = get_pending_deletes(req)
- self.assertEquals(deletes, ['12:tags:13'])
+ self.assertEqual(deletes, ['12:tags:13'])
req.remove_pending_operations()
- self.assertEquals(get_pending_deletes(req), [])
- self.assertEquals(get_pending_inserts(req), [])
+ self.assertEqual(get_pending_deletes(req), [])
+ self.assertEqual(get_pending_inserts(req), [])
def test_add_inserts(self):
res, req = self.remote_call('add_pending_inserts',
[('12', 'tags', '13'), ('12', 'tags', '14')])
inserts = get_pending_inserts(req)
- self.assertEquals(inserts, ['12:tags:13', '12:tags:14'])
+ self.assertEqual(inserts, ['12:tags:13', '12:tags:14'])
req.remove_pending_operations()
# silly tests
def test_external_resource(self):
- self.assertEquals(self.remote_call('external_resource', 'RSS_LOGO')[0],
+ self.assertEqual(self.remote_call('external_resource', 'RSS_LOGO')[0],
json_dumps(self.config.uiprops['RSS_LOGO']))
def test_i18n(self):
- self.assertEquals(self.remote_call('i18n', ['bimboom'])[0],
+ self.assertEqual(self.remote_call('i18n', ['bimboom'])[0],
json_dumps(['bimboom']))
def test_format_date(self):
- self.assertEquals(self.remote_call('format_date', '2007-01-01 12:00:00')[0],
+ self.assertEqual(self.remote_call('format_date', '2007-01-01 12:00:00')[0],
json_dumps('2007/01/01'))
--- a/web/test/unittest_views_basetemplates.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_views_basetemplates.py Wed Sep 29 16:16:32 2010 +0200
@@ -31,9 +31,9 @@
def test_label(self):
self.set_option('allow-email-login', 'yes')
- self.assertEquals(self._login_labels(), ['login or email', 'password'])
+ self.assertEqual(self._login_labels(), ['login or email', 'password'])
self.set_option('allow-email-login', 'no')
- self.assertEquals(self._login_labels(), ['login', 'password'])
+ self.assertEqual(self._login_labels(), ['login', 'password'])
if __name__ == '__main__':
from logilab.common.testlib import unittest_main
--- a/web/test/unittest_views_baseviews.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_views_baseviews.py Wed Sep 29 16:16:32 2010 +0200
@@ -31,56 +31,56 @@
def test_no_rset(self):
req = self.request()
- self.assertEquals(vid_from_rset(req, None, self.schema), 'index')
+ self.assertEqual(vid_from_rset(req, None, self.schema), 'index')
def test_no_entity(self):
req = self.request()
rset = self.execute('Any X WHERE X login "blabla"')
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'noresult')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'noresult')
def test_one_entity(self):
req = self.request()
rset = self.execute('Any X WHERE X login "admin"')
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'primary')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'primary')
rset = self.execute('Any X, L WHERE X login "admin", X login L')
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'primary')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'primary')
req.search_state = ('pasnormal',)
rset = self.execute('Any X WHERE X login "admin"')
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'outofcontext-search')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'outofcontext-search')
def test_one_entity_eid(self):
req = self.request()
rset = self.execute('Any X WHERE X eid 1')
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'primary')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'primary')
def test_more_than_one_entity_same_type(self):
req = self.request()
rset = self.execute('Any X WHERE X is CWUser')
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'sameetypelist')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'sameetypelist')
rset = self.execute('Any X, L WHERE X login L')
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'sameetypelist')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'sameetypelist')
def test_more_than_one_entity_diff_type(self):
req = self.request()
rset = self.execute('Any X WHERE X is IN (CWUser, CWGroup)')
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'list')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'list')
def test_more_than_one_entity_by_row(self):
req = self.request()
rset = self.execute('Any X, G WHERE X in_group G')
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'table')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
def test_more_than_one_entity_by_row_2(self):
req = self.request()
rset = self.execute('Any X, GN WHERE X in_group G, G name GN')
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'table')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
def test_aggregat(self):
req = self.request()
rset = self.execute('Any X, COUNT(T) GROUPBY X WHERE X is T')
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'table')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
rset = self.execute('Any MAX(X) WHERE X is CWUser')
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'table')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
def test_subquery(self):
rset = self.execute(
@@ -90,7 +90,7 @@
' UNION'
' (DISTINCT Any W,N WHERE W is CWGroup, W name N))')
req = self.request()
- self.assertEquals(vid_from_rset(req, rset, self.schema), 'table')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
class TableViewTC(CubicWebTC):
@@ -104,7 +104,7 @@
return e, rset, view
def test_headers(self):
- self.skip('implement me')
+ self.skipTest('implement me')
def test_sortvalue(self):
e, _, view = self._prepare_entity()
--- a/web/test/unittest_views_editforms.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_views_editforms.py Wed Sep 29 16:16:32 2010 +0200
@@ -50,19 +50,19 @@
def test_cwuser_relations_by_category(self):
e = self.vreg['etypes'].etype_class('CWUser')(self.request())
# see custom configuration in views.cwuser
- self.assertEquals(rbc(e, 'main', 'attributes'),
+ self.assertEqual(rbc(e, 'main', 'attributes'),
[('login', 'subject'),
('upassword', 'subject'),
('firstname', 'subject'),
('surname', 'subject'),
('in_group', 'subject'),
])
- self.assertListEquals(rbc(e, 'muledit', 'attributes'),
+ self.assertListEqual(rbc(e, 'muledit', 'attributes'),
[('login', 'subject'),
('upassword', 'subject'),
('in_group', 'subject'),
])
- self.assertListEquals(rbc(e, 'main', 'metadata'),
+ self.assertListEqual(rbc(e, 'main', 'metadata'),
[('last_login_time', 'subject'),
('modification_date', 'subject'),
('created_by', 'subject'),
@@ -74,18 +74,18 @@
# XXX skip 'tags' relation here and in the hidden category because
# of some test interdependancy when pytest is launched on whole cw
# (appears here while expected in hidden
- self.assertListEquals([x for x in rbc(e, 'main', 'relations')
+ self.assertListEqual([x for x in rbc(e, 'main', 'relations')
if x != ('tags', 'object')],
[('primary_email', 'subject'),
('custom_workflow', 'subject'),
('connait', 'subject'),
('checked_by', 'object'),
])
- self.assertListEquals(rbc(e, 'main', 'inlined'),
+ self.assertListEqual(rbc(e, 'main', 'inlined'),
[('use_email', 'subject'),
])
# owned_by is defined both as subject and object relations on CWUser
- self.assertListEquals(sorted(x for x in rbc(e, 'main', 'hidden')
+ self.assertListEqual(sorted(x for x in rbc(e, 'main', 'hidden')
if x != ('tags', 'object')),
sorted([('for_user', 'object'),
('created_by', 'object'),
@@ -100,7 +100,7 @@
def test_personne_relations_by_category(self):
e = self.vreg['etypes'].etype_class('Personne')(self.request())
- self.assertListEquals(rbc(e, 'main', 'attributes'),
+ self.assertListEqual(rbc(e, 'main', 'attributes'),
[('nom', 'subject'),
('prenom', 'subject'),
('sexe', 'subject'),
@@ -115,22 +115,22 @@
('description', 'subject'),
('salary', 'subject'),
])
- self.assertListEquals(rbc(e, 'muledit', 'attributes'),
+ self.assertListEqual(rbc(e, 'muledit', 'attributes'),
[('nom', 'subject'),
])
- self.assertListEquals(rbc(e, 'main', 'metadata'),
+ self.assertListEqual(rbc(e, 'main', 'metadata'),
[('creation_date', 'subject'),
('cwuri', 'subject'),
('modification_date', 'subject'),
('created_by', 'subject'),
('owned_by', 'subject'),
])
- self.assertListEquals(rbc(e, 'main', 'relations'),
+ self.assertListEqual(rbc(e, 'main', 'relations'),
[('travaille', 'subject'),
('manager', 'object'),
('connait', 'object'),
])
- self.assertListEquals(rbc(e, 'main', 'hidden'),
+ self.assertListEqual(rbc(e, 'main', 'hidden'),
[])
def test_edition_form(self):
--- a/web/test/unittest_views_embeding.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_views_embeding.py Wed Sep 29 16:16:32 2010 +0200
@@ -46,7 +46,7 @@
]
for orig_a, expected_a in zip(orig, expected):
got = prefix_links(orig_a, 'PREFIX', 'http://embedded.com/page1.html')
- self.assertEquals(got, expected_a)
+ self.assertEqual(got, expected_a)
if __name__ == '__main__':
unittest_main()
--- a/web/test/unittest_views_navigation.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_views_navigation.py Wed Sep 29 16:16:32 2010 +0200
@@ -62,10 +62,10 @@
req = self.request()
rset = self.execute('Any X,N LIMIT 10 WHERE X name N')
navcomp = self.vreg['components'].select_or_none('navigation', req, rset=rset)
- self.assertEquals(navcomp, None)
+ self.assertEqual(navcomp, None)
req.set_search_state('W:X:Y:Z')
navcomp = self.vreg['components'].select_or_none('navigation', req, rset=rset)
- self.assertEquals(navcomp, None)
+ self.assertEqual(navcomp, None)
req.set_search_state('normal')
def test_navigation_selection_not_enough(self):
--- a/web/test/unittest_views_pyviews.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_views_pyviews.py Wed Sep 29 16:16:32 2010 +0200
@@ -25,7 +25,7 @@
pyvalue=[[1, 'a'], [2, 'b']])
content = view.render(pyvalue=[[1, 'a'], [2, 'b']],
headers=['num', 'char'])
- self.assertEquals(content.strip(), '''<table class="listing">
+ self.assertEqual(content.strip(), '''<table class="listing">
<thead><tr><th>num</th><th>char</th></tr>
</thead><tbody><tr><td>1</td><td>a</td></tr>
<tr><td>2</td><td>b</td></tr>
@@ -35,7 +35,7 @@
view = self.vreg['views'].select('pyvallist', self.request(),
pyvalue=[1, 'a'])
content = view.render(pyvalue=[1, 'a'])
- self.assertEquals(content.strip(), '''<ul>
+ self.assertEqual(content.strip(), '''<ul>
<li>1</li>
<li>a</li>
</ul>''')
--- a/web/test/unittest_views_searchrestriction.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_views_searchrestriction.py Wed Sep 29 16:16:32 2010 +0200
@@ -46,32 +46,32 @@
'B in_group P, P name "managers"')
def test_1(self):
- self.assertEquals(self._generate(self.select, 'in_state', 'subject', 'name'),
+ self.assertEqual(self._generate(self.select, 'in_state', 'subject', 'name'),
"DISTINCT Any A,C ORDERBY C WHERE B in_group P, P name 'managers', "
"B in_state A, B is CWUser, A name C")
def test_2(self):
- self.assertEquals(self._generate(self.select, 'tags', 'object', 'name'),
+ self.assertEqual(self._generate(self.select, 'tags', 'object', 'name'),
"DISTINCT Any A,C ORDERBY C WHERE B in_group P, P name 'managers', "
"A tags B, B is CWUser, A name C")
def test_3(self):
- self.assertEquals(self._generate(self.select, 'created_by', 'subject', 'login'),
+ self.assertEqual(self._generate(self.select, 'created_by', 'subject', 'login'),
"DISTINCT Any A,C ORDERBY C WHERE B in_group P, P name 'managers', "
"B created_by A, B is CWUser, A login C")
def test_4(self):
- self.assertEquals(self._generate(self.parse('Any X WHERE X is CWUser'), 'created_by', 'subject', 'login'),
+ self.assertEqual(self._generate(self.parse('Any X WHERE X is CWUser'), 'created_by', 'subject', 'login'),
"DISTINCT Any A,B ORDERBY B WHERE X is CWUser, X created_by A, A login B")
def test_5(self):
- self.assertEquals(self._generate(self.parse('Any X,L WHERE X is CWUser, X login L'), 'created_by', 'subject', 'login'),
+ self.assertEqual(self._generate(self.parse('Any X,L WHERE X is CWUser, X login L'), 'created_by', 'subject', 'login'),
"DISTINCT Any A,B ORDERBY B WHERE X is CWUser, X created_by A, A login B")
def test_nonregr1(self):
select = self.parse('Any T,V WHERE T bookmarked_by V?, '
'V in_state VS, VS name "published", T created_by U')
- self.assertEquals(self._generate(select, 'created_by', 'subject', 'login'),
+ self.assertEqual(self._generate(select, 'created_by', 'subject', 'login'),
"DISTINCT Any A,B ORDERBY B WHERE T created_by U, "
"T created_by A, T is Bookmark, A login B")
@@ -83,7 +83,7 @@
for rdefs in rschema.rdefs.values():
rdefs.cardinality = '++'
try:
- self.assertEquals(self._generate(select, 'in_state', 'subject', 'name'),
+ self.assertEqual(self._generate(select, 'in_state', 'subject', 'name'),
"DISTINCT Any A,B ORDERBY B WHERE V is CWUser, "
"NOT EXISTS(V in_state VS), VS name 'published', "
"V in_state A, A name B")
@@ -94,7 +94,7 @@
def test_nonregr3(self):
#'DISTINCT Any X,TMP,N WHERE P name TMP, X version_of P, P is Project, X is Version, not X in_state S,S name "published", X num N ORDERBY TMP,N'
select = self.parse('DISTINCT Any X, MAX(Y) GROUPBY X WHERE X is CWUser, Y is Bookmark, X in_group A')
- self.assertEquals(self._generate(select, 'in_group', 'subject', 'name'),
+ self.assertEqual(self._generate(select, 'in_group', 'subject', 'name'),
"DISTINCT Any B,C ORDERBY C WHERE X is CWUser, X in_group B, B name C")
--- a/web/test/unittest_viewselector.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_viewselector.py Wed Sep 29 16:16:32 2010 +0200
@@ -65,7 +65,7 @@
except AttributeError:
return
if registry == 'hooks':
- self.assertEquals(len(content), expected, content)
+ self.assertEqual(len(content), expected, content)
return
try:
self.assertSetEqual(content.keys(), expected)
@@ -467,19 +467,36 @@
def test_properties(self):
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/web/test/unittest_viewselector.py
self.assertEquals(sorted(k for k in self.vreg['propertydefs'].keys()
if k.startswith('ctxcomponents.edit_box')),
['ctxcomponents.edit_box.context',
'ctxcomponents.edit_box.order',
'ctxcomponents.edit_box.visible'])
self.assertEquals([k for k in self.vreg['propertyvalues'].keys()
+=======
+ self.assertEqual(sorted(k for k in self.vreg['propertydefs'].keys()
+ if k.startswith('boxes.edit_box')),
+ ['boxes.edit_box.context',
+ 'boxes.edit_box.order',
+ 'boxes.edit_box.visible'])
+ self.assertEqual([k for k in self.vreg['propertyvalues'].keys()
+>>>>>>> /tmp/unittest_viewselector.py~other.F5zfDM
if not k.startswith('system.version')],
[])
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/web/test/unittest_viewselector.py
self.assertEquals(self.vreg.property_value('ctxcomponents.edit_box.visible'), True)
self.assertEquals(self.vreg.property_value('ctxcomponents.edit_box.order'), 2)
self.assertEquals(self.vreg.property_value('ctxcomponents.possible_views_box.visible'), False)
self.assertEquals(self.vreg.property_value('ctxcomponents.possible_views_box.order'), 10)
self.assertRaises(UnknownProperty, self.vreg.property_value, 'ctxcomponents.actions_box')
+=======
+ self.assertEqual(self.vreg.property_value('boxes.edit_box.visible'), True)
+ self.assertEqual(self.vreg.property_value('boxes.edit_box.order'), 2)
+ self.assertEqual(self.vreg.property_value('boxes.possible_views_box.visible'), False)
+ self.assertEqual(self.vreg.property_value('boxes.possible_views_box.order'), 10)
+ self.assertRaises(UnknownProperty, self.vreg.property_value, 'boxes.actions_box')
+>>>>>>> /tmp/unittest_viewselector.py~other.F5zfDM
--- a/web/test/unittest_web.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/test/unittest_web.py Wed Sep 29 16:16:32 2010 +0200
@@ -25,9 +25,9 @@
req = FakeRequest()
arurl = req.ajax_replace_url
# NOTE: for the simplest use cases, we could use doctest
- self.assertEquals(arurl('foo', rql='Person P', vid='list'),
+ self.assertEqual(arurl('foo', rql='Person P', vid='list'),
"""javascript: $('#foo').loadxhtml("http://testing.fr/cubicweb/json?rql=Person%20P&fname=view&vid=list",null,"get","replace"); noop()""")
- self.assertEquals(arurl('foo', rql='Person P', vid='oneline', name='bar', age=12),
+ self.assertEqual(arurl('foo', rql='Person P', vid='oneline', name='bar', age=12),
"""javascript: $('#foo').loadxhtml("http://testing.fr/cubicweb/json?name=bar&age=12&rql=Person%20P&fname=view&vid=oneline",null,"get","replace"); noop()""")
--- a/web/views/actions.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/views/actions.py Wed Sep 29 16:16:32 2010 +0200
@@ -57,8 +57,7 @@
'optional argument', DeprecationWarning)
editableattrs = form.editable_attributes()
for rschema, role in editableattrs:
- if not rschema.final:
- return 1
+ return 1
return 0
@objectify_selector
@@ -142,8 +141,8 @@
class ModifyAction(action.Action):
__regid__ = 'edit'
- __select__ = (action.Action.__select__ & one_line_rset() &
- (has_permission('update') | has_editable_relation('add')))
+ __select__ = (action.Action.__select__
+ & one_line_rset() & has_editable_relation('add'))
title = _('modify')
category = 'mainactions'
--- a/web/views/basecontrollers.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/views/basecontrollers.py Wed Sep 29 16:16:32 2010 +0200
@@ -154,7 +154,6 @@
else:
req.set_message(req._("You have no access to this view or it can not "
"be used to display the current data."))
- self.warning("the view %s can not be applied to this query", vid)
vid = req.form.get('fallbackvid') or vid_from_rset(req, rset, req.vreg.schema)
view = req.vreg['views'].select(vid, req, rset=rset)
return view, rset
--- a/web/views/cwuser.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/views/cwuser.py Wed Sep 29 16:16:32 2010 +0200
@@ -85,7 +85,8 @@
% xml_escape(entity.firstname))
emailaddr = entity.cw_adapt_to('IEmailable').get_email()
if emailaddr:
- self.w(u'<foaf:mbox_sha1sum>%s</foaf:mbox_sha1sum>\n' % hashlib.sha1(emailaddr).hexdigest())
+ self.w(u'<foaf:mbox_sha1sum>%s</foaf:mbox_sha1sum>\n'
+ % hashlib.sha1(emailaddr.encode('utf-8')).hexdigest())
self.w(u'</foaf:Person>\n')
--- a/web/views/formrenderers.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/views/formrenderers.py Wed Sep 29 16:16:32 2010 +0200
@@ -342,8 +342,14 @@
def render_fields(self, w, form, values):
if form.parent_form is None:
w(u'<table class="listing">')
- subfields = [field for field in form.forms[0].fields
- if field.is_visible()]
+ # get fields from the first subform with something to display (we
+ # may have subforms with nothing editable that will simply be
+ # skipped later)
+ for subform in form.forms:
+ subfields = [field for field in subform.fields
+ if field.is_visible()]
+ if subfields:
+ break
if subfields:
# main form, display table headers
w(u'<tr class="header">')
--- a/web/views/primary.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/views/primary.py Wed Sep 29 16:16:32 2010 +0200
@@ -145,18 +145,23 @@
for rschema, role, dispctrl, value in display_attributes:
if support_args(self._render_attribute, 'label'):
label = self._rel_label(entity, rschema, role, dispctrl)
- self._render_attribute(label, value, table=True)
+ self.render_attribute(label, value, table=True)
elif support_args(self._render_attribute, 'dispctrl'):
- warn('[3.10] _render_attribute prototype has changed, please'
- ' update %s' % self.__class___, DeprecationWarning)
+ warn('[3.9] _render_attribute prototype has changed and '
+ 'renamed to render_attribute, please update %s'
+ % self.__class___, DeprecationWarning)
self._render_attribute(dispctrl, rschema, value, role=role,
table=True)
else:
- warn('[3.6] _render_attribute prototype has changed, please'
- ' update %s' % self.__class___, DeprecationWarning)
self._render_attribute(rschema, value, role=role, table=True)
+ warn('[3.6] _render_attribute prototype has changed and '
+ 'renamed to render_attribute, please update %s'
+ % self.__class___, DeprecationWarning)
self.w(u'</table>')
+ def render_attribute(self, label, value, table=False):
+ self.field(label, value, tr=False, table=table)
+
def render_entity_relations(self, entity):
for rschema, tschemas, role, dispctrl in self._section_def(entity, 'relations'):
if rschema.final or dispctrl.get('rtypevid'):
@@ -164,31 +169,45 @@
try:
rview = self._cw.vreg['views'].select(
vid, self._cw, rset=entity.cw_rset, row=entity.cw_row,
- col=entity.cw_col, dispctrl=dispctrl, rtype=rschema, role=role)
+ col=entity.cw_col, dispctrl=dispctrl,
+ rtype=rschema, role=role)
except NoSelectableObject:
continue
- self.w(u'<div class="section">')
- label = self._rel_label(entity, rschema, role, dispctrl)
- if label:
- self.w(u'<h4>%s</h4>' % label)
- rview.render(row=entity.cw_row, col=entity.cw_col, w=self.w,
- rtype=rschema.type, role=role)
- self.w(u'</div>')
- continue
- rset = self._relation_rset(entity, rschema, role, dispctrl)
- if rset:
- if support_args(self._render_relation, 'label'):
- label = self._rel_label(entity, rschema, role, dispctrl)
- self._render_relation(label, dispctrl, rset, 'autolimited')
- elif not support_args(self._render_relation, 'showlabel'):
- warn('[3.10] _render_relation prototype has changed, '
- 'please update %s' % self.__class__, DeprecationWarning)
- self._render_relation(dispctrl, rset, 'autolimited')
- else:
- warn('[3.6] _render_relation prototype has changed, '
- 'please update %s' % self.__class__, DeprecationWarning)
- self._render_relation(rset, dispctrl, 'autolimited',
- self.show_rel_label)
+ value = rview.render(row=entity.cw_row, col=entity.cw_col,
+ rtype=rschema.type, role=role)
+ else:
+ rset = self._relation_rset(entity, rschema, role, dispctrl)
+ if not rset:
+ continue
+ if hasattr(self, '_render_relation'):
+ if not support_args(self._render_relation, 'showlabel'):
+ self._render_relation(dispctrl, rset, 'autolimited')
+ warn('[3.9] _render_relation prototype has changed and has '
+ 'been renamed to render_relation, please update %s'
+ % self.__class__, DeprecationWarning)
+ else:
+ self._render_relation(rset, dispctrl, 'autolimited',
+ self.show_rel_label)
+ warn('[3.6] _render_relation prototype has changed and has '
+ 'been renamed to render_relation, please update %s'
+ % self.__class__, DeprecationWarning)
+ continue
+ vid = dispctrl.get('vid', 'autolimited')
+ try:
+ rview = self._cw.vreg['views'].select(
+ vid, self._cw, rset=rset, dispctrl=dispctrl)
+ except NoSelectableObject:
+ continue
+ value = rview.render()
+ label = self._rel_label(entity, rschema, role, dispctrl)
+ self.render_relation(label, value)
+
+ def render_relation(self, label, value):
+ self.w(u'<div class="section">')
+ if label:
+ self.w(u'<h4>%s</h4>' % label)
+ self.w(value)
+ self.w(u'</div>')
def render_side_boxes(self, boxes):
"""display side related relations:
@@ -266,17 +285,6 @@
rset = dispctrl['filter'](rset)
return rset
- def _render_relation(self, label, dispctrl, rset, defaultvid):
- self.w(u'<div class="section">')
- if label:
- self.w(u'<h4>%s</h4>' % label)
- self.wview(dispctrl.get('vid', defaultvid), rset,
- initargs={'dispctrl': dispctrl})
- self.w(u'</div>')
-
- def _render_attribute(self, label, value, table=False):
- self.field(label, value, tr=False, table=table)
-
def _rel_label(self, entity, rschema, role, dispctrl):
if rschema.final:
showlabel = dispctrl.get('showlabel', self.show_attr_label)
--- a/web/views/workflow.py Thu Sep 23 23:28:58 2010 +0200
+++ b/web/views/workflow.py Wed Sep 29 16:16:32 2010 +0200
@@ -164,7 +164,7 @@
class WFHistoryVComponent(component.CtxComponent):
"""display the workflow history for entities supporting it"""
__regid__ = 'wfhistory'
- __select__ = WFHistoryView.__select__ & component.EntityVComponent.__select__
+ __select__ = component.EntityVComponent.__select__ & WFHistoryView.__select__
context = 'navcontentbottom'
title = _('Workflow history')