[MERGE] trunk
bzr revid: abo@openerp.com-20130212125650-3r8lsai6p5c8ls2h
This commit is contained in:
commit
fbb51ee106
|
@ -228,45 +228,6 @@ class lang(osv.osv):
|
|||
|
||||
lang()
|
||||
|
||||
def original_group(s, grouping, thousands_sep=''):
|
||||
|
||||
if not grouping:
|
||||
return s, 0
|
||||
|
||||
result = ""
|
||||
seps = 0
|
||||
spaces = ""
|
||||
|
||||
if s[-1] == ' ':
|
||||
sp = s.find(' ')
|
||||
spaces = s[sp:]
|
||||
s = s[:sp]
|
||||
|
||||
while s and grouping:
|
||||
# if grouping is -1, we are done
|
||||
if grouping[0] == -1:
|
||||
break
|
||||
# 0: re-use last group ad infinitum
|
||||
elif grouping[0] != 0:
|
||||
#process last group
|
||||
group = grouping[0]
|
||||
grouping = grouping[1:]
|
||||
if result:
|
||||
result = s[-group:] + thousands_sep + result
|
||||
seps += 1
|
||||
else:
|
||||
result = s[-group:]
|
||||
s = s[:-group]
|
||||
if s and s[-1] not in "0123456789":
|
||||
# the leading string is only spaces and signs
|
||||
return s + result + spaces, seps
|
||||
if not result:
|
||||
return s + spaces, seps
|
||||
if s:
|
||||
result = s + thousands_sep + result
|
||||
seps += 1
|
||||
return result + spaces, seps
|
||||
|
||||
def split(l, counts):
|
||||
"""
|
||||
|
||||
|
@ -317,52 +278,4 @@ def intersperse(string, counts, separator=''):
|
|||
res = separator.join(map(reverse, reverse(splits)))
|
||||
return left + res + right, len(splits) > 0 and len(splits) -1 or 0
|
||||
|
||||
# TODO rewrite this with a unit test library
|
||||
def _group_examples():
|
||||
for g in [original_group, intersperse]:
|
||||
# print "asserts on", g.func_name
|
||||
assert g("", []) == ("", 0)
|
||||
assert g("0", []) == ("0", 0)
|
||||
assert g("012", []) == ("012", 0)
|
||||
assert g("1", []) == ("1", 0)
|
||||
assert g("12", []) == ("12", 0)
|
||||
assert g("123", []) == ("123", 0)
|
||||
assert g("1234", []) == ("1234", 0)
|
||||
assert g("123456789", []) == ("123456789", 0)
|
||||
assert g("&ab%#@1", []) == ("&ab%#@1", 0)
|
||||
|
||||
assert g("0", []) == ("0", 0)
|
||||
assert g("0", [1]) == ("0", 0)
|
||||
assert g("0", [2]) == ("0", 0)
|
||||
assert g("0", [200]) == ("0", 0)
|
||||
|
||||
# breaks original_group:
|
||||
if g.func_name == 'intersperse':
|
||||
assert g("12345678", [0], '.') == ('12345678', 0)
|
||||
assert g("", [1], '.') == ('', 0)
|
||||
assert g("12345678", [1], '.') == ('1234567.8', 1)
|
||||
assert g("12345678", [1], '.') == ('1234567.8', 1)
|
||||
assert g("12345678", [2], '.') == ('123456.78', 1)
|
||||
assert g("12345678", [2,1], '.') == ('12345.6.78', 2)
|
||||
assert g("12345678", [2,0], '.') == ('12.34.56.78', 3)
|
||||
assert g("12345678", [-1,2], '.') == ('12345678', 0)
|
||||
assert g("12345678", [2,-1], '.') == ('123456.78', 1)
|
||||
assert g("12345678", [2,0,1], '.') == ('12.34.56.78', 3)
|
||||
assert g("12345678", [2,0,0], '.') == ('12.34.56.78', 3)
|
||||
assert g("12345678", [2,0,-1], '.') == ('12.34.56.78', 3)
|
||||
assert g("12345678", [3,3,3,3], '.') == ('12.345.678', 2)
|
||||
|
||||
assert original_group("abc1234567xy", [2], '.') == ('abc1234567.xy', 1)
|
||||
assert original_group("abc1234567xy8", [2], '.') == ('abc1234567xy8', 0) # difference here...
|
||||
assert original_group("abc12", [3], '.') == ('abc12', 0)
|
||||
assert original_group("abc12", [2], '.') == ('abc12', 0)
|
||||
assert original_group("abc12", [1], '.') == ('abc1.2', 1)
|
||||
|
||||
assert intersperse("abc1234567xy", [2], '.') == ('abc1234567.xy', 1)
|
||||
assert intersperse("abc1234567xy8", [2], '.') == ('abc1234567x.y8', 1) # ... w.r.t. here.
|
||||
assert intersperse("abc12", [3], '.') == ('abc12', 0)
|
||||
assert intersperse("abc12", [2], '.') == ('abc12', 0)
|
||||
assert intersperse("abc12", [1], '.') == ('abc1.2', 1)
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
import sys
|
||||
import openerp
|
||||
|
||||
import openerp.addons.base.res.res_lang as res_lang
|
||||
res_lang._group_examples()
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,27 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2011-TODAY OpenERP S.A. <http://www.openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Useful for manual testing of cron jobs scheduling.
|
||||
# This must be (un)commented with the corresponding yml file
|
||||
# in ../__openerp__.py.
|
||||
# import test_ir_cron
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -3,6 +3,7 @@ import test_expression
|
|||
import test_ir_attachment
|
||||
import test_ir_values
|
||||
import test_menu
|
||||
import test_res_lang
|
||||
import test_search
|
||||
|
||||
checks = [
|
||||
|
@ -11,5 +12,6 @@ checks = [
|
|||
test_ir_attachment,
|
||||
test_ir_values,
|
||||
test_menu,
|
||||
test_res_lang,
|
||||
test_search,
|
||||
]
|
||||
|
|
|
@ -40,4 +40,4 @@ class test_base(common.TransactionCase):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest2.main()
|
||||
unittest2.main()
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import unittest2
|
||||
|
||||
import openerp.tests.common as common
|
||||
|
||||
class test_res_lang(common.TransactionCase):
|
||||
|
||||
def test_00_intersperse(self):
|
||||
from openerp.addons.base.res.res_lang import intersperse
|
||||
|
||||
assert intersperse("", []) == ("", 0), "Assert passed"
|
||||
assert intersperse("0", []) == ("0", 0), "Assert passed"
|
||||
assert intersperse("012", []) == ("012", 0), "Assert passed"
|
||||
assert intersperse("1", []) == ("1", 0), "Assert passed"
|
||||
assert intersperse("12", []) == ("12", 0), "Assert passed"
|
||||
assert intersperse("123", []) == ("123", 0), "Assert passed"
|
||||
assert intersperse("1234", []) == ("1234", 0), "Assert passed"
|
||||
assert intersperse("123456789", []) == ("123456789", 0), "Assert passed"
|
||||
assert intersperse("&ab%#@1", []) == ("&ab%#@1", 0), "Assert passed"
|
||||
|
||||
assert intersperse("0", []) == ("0", 0), "Assert passed"
|
||||
assert intersperse("0", [1]) == ("0", 0), "Assert passed"
|
||||
assert intersperse("0", [2]) == ("0", 0), "Assert passed"
|
||||
assert intersperse("0", [200]) == ("0", 0), "Assert passed"
|
||||
|
||||
assert intersperse("12345678", [1], '.') == ('1234567.8', 1)
|
||||
assert intersperse("12345678", [1], '.') == ('1234567.8', 1)
|
||||
assert intersperse("12345678", [2], '.') == ('123456.78', 1)
|
||||
assert intersperse("12345678", [2,1], '.') == ('12345.6.78', 2)
|
||||
assert intersperse("12345678", [2,0], '.') == ('12.34.56.78', 3)
|
||||
assert intersperse("12345678", [-1,2], '.') == ('12345678', 0)
|
||||
assert intersperse("12345678", [2,-1], '.') == ('123456.78', 1)
|
||||
assert intersperse("12345678", [2,0,1], '.') == ('12.34.56.78', 3)
|
||||
assert intersperse("12345678", [2,0,0], '.') == ('12.34.56.78', 3)
|
||||
assert intersperse("12345678", [2,0,-1], '.') == ('12.34.56.78', 3)
|
||||
assert intersperse("12345678", [3,3,3,3], '.') == ('12.345.678', 2)
|
||||
|
||||
assert intersperse("abc1234567xy", [2], '.') == ('abc1234567.xy', 1)
|
||||
assert intersperse("abc1234567xy8", [2], '.') == ('abc1234567x.y8', 1) # ... w.r.t. here.
|
||||
assert intersperse("abc12", [3], '.') == ('abc12', 0)
|
||||
assert intersperse("abc12", [2], '.') == ('abc12', 0)
|
||||
assert intersperse("abc12", [1], '.') == ('abc1.2', 1)
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -400,7 +400,7 @@ def load_openerp_module(module_name):
|
|||
initialize_sys_path()
|
||||
try:
|
||||
mod_path = get_module_path(module_name)
|
||||
zip_mod_path = mod_path + '.zip'
|
||||
zip_mod_path = '' if not mod_path else mod_path + '.zip'
|
||||
if not os.path.isfile(zip_mod_path):
|
||||
__import__('openerp.addons.' + module_name)
|
||||
else:
|
||||
|
|
|
@ -216,6 +216,11 @@ class RegistryManager(object):
|
|||
del cls.registries[db_name]
|
||||
raise
|
||||
|
||||
# load_modules() above can replace the registry by calling
|
||||
# indirectly new() again (when modules have to be uninstalled).
|
||||
# Yeah, crazy.
|
||||
registry = cls.registries[db_name]
|
||||
|
||||
cr = registry.db.cursor()
|
||||
try:
|
||||
Registry.setup_multi_process_signaling(cr)
|
||||
|
|
|
@ -1077,7 +1077,7 @@ class BaseModel(object):
|
|||
|
||||
# Validate rec_name
|
||||
if self._rec_name is not None:
|
||||
assert self._rec_name in self._columns.keys() + ['id'], "Invalid rec_name %s for model %s" % (self._rec_name, self._name)
|
||||
assert self._rec_name in self._all_columns.keys() + ['id'], "Invalid rec_name %s for model %s" % (self._rec_name, self._name)
|
||||
else:
|
||||
self._rec_name = 'name'
|
||||
|
||||
|
@ -1362,11 +1362,9 @@ class BaseModel(object):
|
|||
noupdate=noupdate, res_id=id, context=context))
|
||||
cr.execute('RELEASE SAVEPOINT model_load_save')
|
||||
except psycopg2.Warning, e:
|
||||
_logger.exception('Failed to import record %s', record)
|
||||
messages.append(dict(info, type='warning', message=str(e)))
|
||||
cr.execute('ROLLBACK TO SAVEPOINT model_load_save')
|
||||
except psycopg2.Error, e:
|
||||
_logger.exception('Failed to import record %s', record)
|
||||
messages.append(dict(
|
||||
info, type='error',
|
||||
**PGERROR_TO_OE[e.pgcode](self, fg, info, e)))
|
||||
|
@ -5328,11 +5326,28 @@ def convert_pgerror_23502(model, fields, info, e):
|
|||
'message': message,
|
||||
'field': field_name,
|
||||
}
|
||||
def convert_pgerror_23505(model, fields, info, e):
|
||||
m = re.match(r'^duplicate key (?P<field>\w+) violates unique constraint',
|
||||
str(e))
|
||||
field_name = m.group('field')
|
||||
if not m or field_name not in fields:
|
||||
return {'message': unicode(e)}
|
||||
message = _(u"The value for the field '%s' already exists.") % field_name
|
||||
field = fields.get(field_name)
|
||||
if field:
|
||||
message = _(u"%s This might be '%s' in the current model, or a field "
|
||||
u"of the same name in an o2m.") % (message, field['string'])
|
||||
return {
|
||||
'message': message,
|
||||
'field': field_name,
|
||||
}
|
||||
|
||||
PGERROR_TO_OE = collections.defaultdict(
|
||||
# shape of mapped converters
|
||||
lambda: (lambda model, fvg, info, pgerror: {'message': unicode(pgerror)}), {
|
||||
# not_null_violation
|
||||
'23502': convert_pgerror_23502,
|
||||
# unique constraint error
|
||||
'23505': convert_pgerror_23505,
|
||||
})
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -189,6 +189,8 @@ class rml_parse(object):
|
|||
return newtag, attrs
|
||||
|
||||
def _ellipsis(self, char, size=100, truncation_str='...'):
|
||||
if not char:
|
||||
return ''
|
||||
if len(char) <= size:
|
||||
return char
|
||||
return char[:size-len(truncation_str)] + truncation_str
|
||||
|
|
|
@ -319,7 +319,13 @@ class WorkerHTTP(Worker):
|
|||
fcntl.fcntl(client, fcntl.F_SETFD, flags)
|
||||
# do request using WorkerBaseWSGIServer monkey patched with socket
|
||||
self.server.socket = client
|
||||
self.server.process_request(client,addr)
|
||||
# tolerate broken pipe when the http client closes the socket before
|
||||
# receiving the full reply
|
||||
try:
|
||||
self.server.process_request(client,addr)
|
||||
except IOError, e:
|
||||
if e.errno != errno.EPIPE:
|
||||
raise
|
||||
self.request_count += 1
|
||||
|
||||
def process_work(self):
|
||||
|
|
|
@ -23,3 +23,4 @@ access_export_one2many_child_2,access_export_one2many_child_2,model_export_one2m
|
|||
access_export_many2many_other,access_export_many2many_other,model_export_many2many_other,,1,1,1,1
|
||||
access_export_selection_withdefault,access_export_selection_withdefault,model_export_selection_withdefault,,1,1,1,1
|
||||
access_export_one2many_recursive,access_export_one2many_recursive,model_export_one2many_recursive,,1,1,1,1
|
||||
access_export_unique,access_export_unique,model_export_unique,,1,1,1,1
|
||||
|
|
|
|
@ -144,3 +144,13 @@ class RecO2M(orm.Model):
|
|||
'value': fields.integer(),
|
||||
'child': fields.one2many('export.one2many.multiple', 'parent_id')
|
||||
}
|
||||
|
||||
class OnlyOne(orm.Model):
|
||||
_name = 'export.unique'
|
||||
|
||||
_columns = {
|
||||
'value': fields.integer(),
|
||||
}
|
||||
_sql_constraints = [
|
||||
('value_unique', 'unique (value)', "The value must be unique"),
|
||||
]
|
||||
|
|
|
@ -1149,3 +1149,29 @@ class test_datetime(ImporterCase):
|
|||
self.assertEqual(
|
||||
values(self.read(domain=[('id', 'in', result['ids'])])),
|
||||
['2012-02-03 11:11:11'])
|
||||
|
||||
class test_unique(ImporterCase):
|
||||
model_name = 'export.unique'
|
||||
|
||||
@mute_logger('openerp.sql_db')
|
||||
def test_unique(self):
|
||||
result = self.import_(['value'], [
|
||||
['1'],
|
||||
['1'],
|
||||
['2'],
|
||||
['3'],
|
||||
['3'],
|
||||
])
|
||||
self.assertFalse(result['ids'])
|
||||
self.assertEqual(result['messages'], [
|
||||
dict(message=u"The value for the field 'value' already exists. "
|
||||
u"This might be 'unknown' in the current model, "
|
||||
u"or a field of the same name in an o2m.",
|
||||
type='error', rows={'from': 1, 'to': 1},
|
||||
record=1, field='value'),
|
||||
dict(message=u"The value for the field 'value' already exists. "
|
||||
u"This might be 'unknown' in the current model, "
|
||||
u"or a field of the same name in an o2m.",
|
||||
type='error', rows={'from': 4, 'to': 4},
|
||||
record=4, field='value'),
|
||||
])
|
||||
|
|
Loading…
Reference in New Issue