diff --git a/doc/test-framework.rst b/doc/test-framework.rst index 56951b1a8e1..17a7b480640 100644 --- a/doc/test-framework.rst +++ b/doc/test-framework.rst @@ -87,9 +87,9 @@ In addition to the above possibilities, when invoked with a non-existing module sub-modules. Depending on the unittest2_ class that is used to write the tests (see -``openerp.tests.common`` for some helper classes that you can re-use), a database -may be created before the test is run, and the module providing the test will -be installed on that database. +:mod:`openerp.tests.common` for some helper classes that you can re-use), a +database may be created before the test is run, and the module providing the +test will be installed on that database. Because creating a database, installing modules, and then dropping it is expensive, it is possible to interleave the run of the ``fast_suite`` tests @@ -98,3 +98,20 @@ each requested module is installed, its fast_suite tests are run. The database is thus created and dropped (and the modules installed) only once. .. _unittest2: http://pypi.python.org/pypi/unittest2 + +TestCase subclasses +------------------- + +.. automodule:: openerp.tests.common + :members: + +.. note:: + + The `setUp` and `tearDown` methods are not part of the tests. Uncaught + exceptions in those methods are errors, not test failures. In particular, + a failing `setUp` will not be followed by a `tearDown` causing any + allocated resource in the `setUp` to not be released by the `tearDown`. + + In the :py:class:`openerp.tests.common.TransactionCase` and + :py:class:`openerp.tests.common.SingleTransactionCase`, this means the + test suite can hang because of unclosed cursors. diff --git a/openerp-server b/openerp-server index 9025e2d50c2..5501eba2159 100755 --- a/openerp-server +++ b/openerp-server @@ -101,6 +101,7 @@ def preload_registry(dbname): def run_test_file(dbname, test_file): """ Preload a registry, possibly run a test file, and start the cron.""" try: + config = openerp.tools.config db, registry = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False) cr = db.cursor() _logger.info('loading test file %s', test_file) diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py index d4e7098c282..1f2caadc54e 100644 --- a/openerp/addons/base/__openerp__.py +++ b/openerp/addons/base/__openerp__.py @@ -86,14 +86,11 @@ The kernel of OpenERP, needed for all installation. 'security/base_security.xml', 'security/ir.model.access.csv', 'security/ir.model.access-1.csv', # res.partner.address is deprecated; it is still there for backward compability only and will be removed in next version - 'res/res_widget_view.xml', - 'res/res_widget_data.xml', ], 'demo': [ 'base_demo.xml', 'res/res_partner_demo.xml', 'res/res_partner_demo.yml', - 'res/res_widget_demo.xml', ], 'test': [ 'test/base_test.xml', diff --git a/openerp/addons/base/i18n/ru.po b/openerp/addons/base/i18n/ru.po index 0e97644b80e..7969b36fc35 100644 --- a/openerp/addons/base/i18n/ru.po +++ b/openerp/addons/base/i18n/ru.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-10-23 18:39+0000\n" +"PO-Revision-Date: 2012-10-25 07:14+0000\n" "Last-Translator: Chertykov Denis \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-24 04:55+0000\n" -"X-Generator: Launchpad (build 16179)\n" +"X-Launchpad-Export-Date: 2012-10-26 04:55+0000\n" +"X-Generator: Launchpad (build 16194)\n" #. module: base #: model:res.country,name:base.sh @@ -4520,7 +4520,7 @@ msgstr "Португалия" #. module: base #: model:ir.module.module,shortdesc:base.module_share msgid "Share any Document" -msgstr "Совместный доступ r любым документам" +msgstr "Совместный доступ к любым документам" #. module: base #: field:ir.module.module,certificate:0 diff --git a/openerp/addons/base/i18n/sl.po b/openerp/addons/base/i18n/sl.po index e2cccabd4d0..cdf2945a44b 100644 --- a/openerp/addons/base/i18n/sl.po +++ b/openerp/addons/base/i18n/sl.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-02-08 00:44+0000\n" -"PO-Revision-Date: 2012-08-20 15:52+0000\n" -"Last-Translator: Mustufa Rangwala (Open ERP) \n" +"PO-Revision-Date: 2012-11-01 18:59+0000\n" +"Last-Translator: Dusan Laznik \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-20 05:04+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-02 05:09+0000\n" +"X-Generator: Launchpad (build 16218)\n" #. module: base #: model:res.country,name:base.sh @@ -34,7 +34,7 @@ msgstr "DatumČas" #. module: base #: model:ir.module.module,shortdesc:base.module_project_mailgate msgid "Tasks-Mail Integration" -msgstr "" +msgstr "Integracija email-opravila" #. module: base #: code:addons/fields.py:582 @@ -90,7 +90,7 @@ msgstr "Delovni proces" #. module: base #: selection:ir.sequence,implementation:0 msgid "No gap" -msgstr "" +msgstr "Bez razmaka" #. module: base #: selection:base.language.install,lang:0 @@ -179,7 +179,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_web_process msgid "Process" -msgstr "" +msgstr "Proces" #. module: base #: model:ir.module.module,shortdesc:base.module_analytic_journal_billing_rate @@ -271,7 +271,7 @@ msgstr "Inuktitut / ᐃᓄᒃᑎᑐᑦ" #: model:ir.module.category,name:base.module_category_sales_management #: model:ir.module.module,shortdesc:base.module_sale msgid "Sales Management" -msgstr "" +msgstr "Prodaja" #. module: base #: view:res.partner:0 @@ -372,12 +372,12 @@ msgstr "" #. module: base #: model:ir.module.category,name:base.module_category_customer_relationship_management msgid "Customer Relationship Management" -msgstr "" +msgstr "Upravljanje odnosov s kupci (CRM)" #. module: base #: view:ir.module.module:0 msgid "Extra" -msgstr "" +msgstr "Dodatno" #. module: base #: code:addons/orm.py:2526 @@ -388,7 +388,7 @@ msgstr "Neveljavna skupina_z" #. module: base #: field:ir.module.category,child_ids:0 msgid "Child Applications" -msgstr "" +msgstr "Podrejene aplikacije" #. module: base #: field:res.partner,credit_limit:0 @@ -539,7 +539,7 @@ msgstr "" #. module: base #: view:ir.values:0 msgid "Action Binding" -msgstr "" +msgstr "Povezovanje akcij" #. module: base #: model:res.country,name:base.gf @@ -702,7 +702,7 @@ msgstr "Izvoz zaključen" #. module: base #: model:ir.module.module,shortdesc:base.module_plugin_outlook msgid "Outlook Plug-In" -msgstr "" +msgstr "Vtičnik za Outlook" #. module: base #: view:ir.model:0 @@ -745,7 +745,7 @@ msgstr "Eritreja" #. module: base #: sql_constraint:res.company:0 msgid "The company name must be unique !" -msgstr "" +msgstr "Ime podjetja mora biti unikatno !" #. module: base #: view:res.config:0 @@ -1006,7 +1006,7 @@ msgstr "Zahtevaj tipe sklicov" #. module: base #: model:ir.module.module,shortdesc:base.module_google_base_account msgid "Google Users" -msgstr "" +msgstr "Google uporabniki" #. module: base #: help:ir.server.object.lines,value:0 @@ -1069,7 +1069,7 @@ msgstr "Vrsta" #. module: base #: field:ir.mail_server,smtp_user:0 msgid "Username" -msgstr "" +msgstr "Uporabnik" #. module: base #: code:addons/orm.py:398 @@ -1217,12 +1217,12 @@ msgstr "Špansko (GT) / Español (GT)" #. module: base #: field:ir.mail_server,smtp_port:0 msgid "SMTP Port" -msgstr "" +msgstr "SMTP vrata" #. module: base #: model:ir.module.module,shortdesc:base.module_import_sugarcrm msgid "SugarCRM Import" -msgstr "" +msgstr "Uvoz iz SugarCRM-a" #. module: base #: view:res.lang:0 @@ -1239,12 +1239,12 @@ msgstr "" #: code:addons/base/module/wizard/base_language_install.py:55 #, python-format msgid "Language Pack" -msgstr "" +msgstr "Jezikovni paket" #. module: base #: model:ir.module.module,shortdesc:base.module_web_tests msgid "Tests" -msgstr "" +msgstr "Preizkusi" #. module: base #: field:ir.ui.view_sc,res_id:0 @@ -1305,7 +1305,7 @@ msgstr "" #. module: base #: field:ir.module.category,parent_id:0 msgid "Parent Application" -msgstr "" +msgstr "Nadrejena aplikacija" #. module: base #: code:addons/base/res/res_users.py:222 @@ -1322,12 +1322,12 @@ msgstr "Ne izbirajte jezika za izvoz novega jezika." #: model:ir.module.module,shortdesc:base.module_document #: model:ir.module.module,shortdesc:base.module_knowledge msgid "Document Management System" -msgstr "" +msgstr "Sistem za upravljanje dokumentov" #. module: base #: model:ir.module.module,shortdesc:base.module_crm_claim msgid "Claims Management" -msgstr "" +msgstr "Pritožbe" #. module: base #: model:ir.ui.menu,name:base.menu_purchase_root @@ -1542,7 +1542,7 @@ msgstr "Prijava" #: model:ir.actions.act_window,name:base.action_wizard_update_translations #: model:ir.ui.menu,name:base.menu_wizard_update_translations msgid "Synchronize Terms" -msgstr "" +msgstr "Sinhronizacija izrazov" #. module: base #: view:ir.actions.server:0 @@ -1585,7 +1585,7 @@ msgstr "Plavajoče" #: model:ir.module.category,name:base.module_category_warehouse_management #: model:ir.module.module,shortdesc:base.module_stock msgid "Warehouse Management" -msgstr "" +msgstr "Skladiščno poslovanje" #. module: base #: model:ir.model,name:base.model_res_request_link @@ -1799,7 +1799,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_html_view msgid "Html View" -msgstr "" +msgstr "Pogled html" #. module: base #: field:res.currency,position:0 @@ -1809,7 +1809,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_process msgid "Enterprise Process" -msgstr "" +msgstr "Proces podjetja" #. module: base #: help:ir.cron,function:0 @@ -1868,7 +1868,7 @@ msgstr "Pripeti model" #. module: base #: field:res.partner.bank,footer:0 msgid "Display on Reports" -msgstr "" +msgstr "Prikaz na poročilih" #. module: base #: model:ir.module.module,description:base.module_l10n_cn @@ -1943,7 +1943,7 @@ msgstr "%s (kopija)" #. module: base #: model:ir.module.module,shortdesc:base.module_account_chart msgid "Template of Charts of Accounts" -msgstr "" +msgstr "Predloga kontnega načrta" #. module: base #: field:res.partner.address,type:0 @@ -2030,12 +2030,12 @@ msgstr "Finska" #: code:addons/base/res/res_company.py:156 #, python-format msgid "Website: " -msgstr "" +msgstr "Spletna stran: " #. module: base #: model:ir.ui.menu,name:base.menu_administration msgid "Settings" -msgstr "" +msgstr "Nastavitve" #. module: base #: selection:ir.actions.act_window,view_type:0 @@ -2175,7 +2175,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_subscription msgid "Recurring Documents" -msgstr "" +msgstr "Ponavljajoči dokumenti" #. module: base #: model:res.country,name:base.bs @@ -2214,7 +2214,7 @@ msgstr "Število osveženih modulov" #. module: base #: field:ir.cron,function:0 msgid "Method" -msgstr "" +msgstr "Način" #. module: base #: view:res.partner.event:0 @@ -2353,7 +2353,7 @@ msgstr "" #. module: base #: field:ir.mail_server,smtp_debug:0 msgid "Debugging" -msgstr "" +msgstr "Razhroščevanje" #. module: base #: model:ir.module.module,description:base.module_crm_helpdesk @@ -2463,7 +2463,7 @@ msgstr "Trenutno razmerje" #. module: base #: model:ir.module.module,shortdesc:base.module_idea msgid "Ideas" -msgstr "" +msgstr "Ideje" #. module: base #: model:ir.module.module,shortdesc:base.module_sale_crm @@ -2505,7 +2505,7 @@ msgstr "" #. module: base #: model:ir.ui.menu,name:base.menu_invoiced msgid "Invoicing" -msgstr "" +msgstr "Izdajanje računov" #. module: base #: field:ir.ui.view_sc,name:0 @@ -2546,7 +2546,7 @@ msgstr "" #: field:ir.model.data,res_id:0 #: field:ir.values,res_id:0 msgid "Record ID" -msgstr "" +msgstr "ID zapisa" #. module: base #: field:ir.actions.server,email:0 @@ -2630,7 +2630,7 @@ msgstr "Napaka pri komuniciranju s strežnikom založniške garancije." #: model:res.groups,name:base.group_sale_manager #: model:res.groups,name:base.group_tool_manager msgid "Manager" -msgstr "" +msgstr "Vodja" #. module: base #: model:ir.ui.menu,name:base.menu_custom @@ -2667,7 +2667,7 @@ msgstr "Počiši ID-je" #. module: base #: view:res.groups:0 msgid "Inherited" -msgstr "" +msgstr "Podedovano" #. module: base #: field:ir.model.fields,serialization_field_id:0 @@ -2690,7 +2690,7 @@ msgstr "%y - Leto brez stoletja [00,99]." #: code:addons/base/res/res_company.py:155 #, python-format msgid "Fax: " -msgstr "" +msgstr "Fax: " #. module: base #: model:res.country,name:base.si @@ -2700,7 +2700,7 @@ msgstr "Slovenija" #. module: base #: help:res.currency,name:0 msgid "Currency Code (ISO 4217)" -msgstr "" +msgstr "Šifra valute (ISO 4217)" #. module: base #: model:ir.actions.act_window,name:base.res_log_act_window @@ -2818,14 +2818,14 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_stock_planning msgid "Master Procurement Schedule" -msgstr "" +msgstr "Planiranje nabave" #. module: base #: model:ir.model,name:base.model_ir_module_category #: field:ir.module.module,application:0 #: field:res.groups,category_id:0 msgid "Application" -msgstr "" +msgstr "Program" #. module: base #: selection:publisher_warranty.contract,state:0 @@ -3019,7 +3019,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_wiki_quality_manual msgid "Wiki: Quality Manual" -msgstr "" +msgstr "Wiki: Priročnik kvalitete" #. module: base #: selection:ir.actions.act_window.view,view_mode:0 @@ -3047,7 +3047,7 @@ msgstr "Sektor HR" #. module: base #: model:ir.ui.menu,name:base.menu_dashboard_admin msgid "Administration Dashboard" -msgstr "" +msgstr "Nadzorna plošča administracije" #. module: base #: code:addons/orm.py:4408 @@ -3138,7 +3138,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_hr_contract msgid "Employee Contracts" -msgstr "" +msgstr "Pogodbe zaposlenih" #. module: base #: model:ir.module.module,description:base.module_wiki_faq @@ -3191,7 +3191,7 @@ msgstr "Naziv kontakta" #. module: base #: model:ir.module.module,shortdesc:base.module_product_manufacturer msgid "Products Manufacturers" -msgstr "" +msgstr "Proizvajalci" #. module: base #: code:addons/base/ir/ir_mail_server.py:217 @@ -3202,7 +3202,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_survey msgid "Survey" -msgstr "" +msgstr "Vprašalnik" #. module: base #: view:base.language.import:0 @@ -3498,7 +3498,7 @@ msgstr "" #: model:ir.module.category,name:base.module_category_generic_modules_accounting #: view:res.company:0 msgid "Accounting" -msgstr "" +msgstr "Računovodstvo" #. module: base #: model:ir.module.module,description:base.module_account_payment @@ -3543,7 +3543,7 @@ msgstr "" #. module: base #: constraint:res.partner:0 msgid "Error ! You cannot create recursive associated members." -msgstr "" +msgstr "Napaka! Ne morete ustvariti rekurzivno povezane člane." #. module: base #: view:res.payterm:0 @@ -3618,7 +3618,7 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_point_of_sale msgid "Point Of Sale" -msgstr "" +msgstr "Prodajno mesto" #. module: base #: code:addons/base/module/module.py:302 @@ -3654,7 +3654,7 @@ msgstr "" #. module: base #: selection:ir.sequence,implementation:0 msgid "Standard" -msgstr "" +msgstr "Običajno" #. module: base #: model:ir.model,name:base.model_maintenance_contract @@ -3687,7 +3687,7 @@ msgstr "" #. module: base #: model:ir.module.category,name:base.module_category_human_resources msgid "Human Resources" -msgstr "" +msgstr "Človeški viri" #. module: base #: model:ir.actions.act_window,name:base.action_country @@ -3747,7 +3747,7 @@ msgstr "DDV" #. module: base #: field:res.users,new_password:0 msgid "Set password" -msgstr "" +msgstr "Nastavite geslo" #. module: base #: view:res.lang:0 @@ -4251,7 +4251,7 @@ msgstr "Povzetek" #. module: base #: model:ir.module.category,name:base.module_category_hidden_dependency msgid "Dependency" -msgstr "" +msgstr "Odvisnost" #. module: base #: field:multi_company.default,expression:0 @@ -4582,7 +4582,7 @@ msgstr "Pravila" #. module: base #: field:ir.mail_server,smtp_host:0 msgid "SMTP Server" -msgstr "" +msgstr "Strežnik SMTP" #. module: base #: code:addons/base/module/module.py:256 @@ -4672,7 +4672,7 @@ msgstr "Kenija" #: model:ir.actions.act_window,name:base.action_translation #: model:ir.ui.menu,name:base.menu_action_translation msgid "Translated Terms" -msgstr "" +msgstr "Prevedeni izrazi" #. module: base #: view:res.partner.event:0 @@ -5003,7 +5003,7 @@ msgstr "" #. module: base #: model:ir.module.category,name:base.module_category_localization msgid "Localization" -msgstr "" +msgstr "Lokalizacija" #. module: base #: model:ir.module.module,description:base.module_sale_mrp @@ -5096,7 +5096,7 @@ msgstr "Decimalni ločevalnik" #: view:ir.module.module:0 #, python-format msgid "Install" -msgstr "" +msgstr "Namesti" #. module: base #: model:ir.actions.act_window,help:base.action_res_groups @@ -5118,7 +5118,7 @@ msgstr "" #. module: base #: field:ir.filters,name:0 msgid "Filter Name" -msgstr "" +msgstr "Ime filtra" #. module: base #: view:res.partner:0 @@ -5225,7 +5225,7 @@ msgstr "Polje" #. module: base #: model:ir.module.module,shortdesc:base.module_project_long_term msgid "Long Term Projects" -msgstr "" +msgstr "Dolgoročni projekti" #. module: base #: model:res.country,name:base.ve @@ -5628,7 +5628,7 @@ msgstr "Svalbardovi in Jan Mayenovi otoki" #. module: base #: model:ir.module.category,name:base.module_category_hidden_test msgid "Test" -msgstr "" +msgstr "Test" #. module: base #: model:ir.module.module,shortdesc:base.module_web_kanban @@ -5718,7 +5718,7 @@ msgstr "Lastnost 'on_delete' za za 'many2one' polja" #. module: base #: model:ir.module.category,name:base.module_category_accounting_and_finance msgid "Accounting & Finance" -msgstr "" +msgstr "Računovodstvo & Finance" #. module: base #: field:ir.actions.server,write_id:0 @@ -5746,7 +5746,7 @@ msgstr "" #: model:ir.module.category,name:base.module_category_usability #: view:res.users:0 msgid "Usability" -msgstr "" +msgstr "Uporabnost" #. module: base #: field:ir.actions.act_window,domain:0 @@ -5797,7 +5797,7 @@ msgstr "Ime skupine se ne sme začeti z \"-\"" #. module: base #: view:ir.module.module:0 msgid "Apps" -msgstr "" +msgstr "Programi" #. module: base #: view:ir.ui.view_sc:0 @@ -5853,7 +5853,7 @@ msgstr "Lastnik bančnega računa" #. module: base #: model:ir.module.category,name:base.module_category_uncategorized msgid "Uncategorized" -msgstr "" +msgstr "Neopredeljeno" #. module: base #: field:ir.attachment,res_name:0 @@ -5921,7 +5921,7 @@ msgstr "" #. module: base #: view:res.partner.bank:0 msgid "My Banks" -msgstr "" +msgstr "Moje banke" #. module: base #: help:multi_company.default,object_id:0 @@ -6003,12 +6003,12 @@ msgstr "" #. module: base #: model:ir.module.module,shortdesc:base.module_base_report_creator msgid "Query Builder" -msgstr "" +msgstr "Čarovnik za poizvedbe" #. module: base #: selection:ir.actions.todo,type:0 msgid "Launch Automatically" -msgstr "" +msgstr "Zaženi samodejno" #. module: base #: model:ir.module.module,description:base.module_mail @@ -6141,7 +6141,7 @@ msgstr "" #: code:addons/base/module/module.py:392 #, python-format msgid "Uninstall" -msgstr "" +msgstr "Odstrani" #. module: base #: model:ir.module.module,shortdesc:base.module_account_budget @@ -6161,7 +6161,7 @@ msgstr "" #. module: base #: selection:ir.mail_server,smtp_encryption:0 msgid "SSL/TLS" -msgstr "" +msgstr "SSL/TLS" #. module: base #: field:publisher_warranty.contract,check_opw:0 diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 8e406519d15..aacd6aa29c2 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -142,13 +142,13 @@ class report_xml(osv.osv): } _defaults = { - 'type': lambda *a: 'ir.actions.report.xml', - 'multi': lambda *a: False, - 'auto': lambda *a: True, - 'header': lambda *a: True, - 'report_sxw_content': lambda *a: False, - 'report_type': lambda *a: 'pdf', - 'attachment': lambda *a: False, + 'type': 'ir.actions.report.xml', + 'multi': False, + 'auto': True, + 'header': True, + 'report_sxw_content': False, + 'report_type': 'pdf', + 'attachment': False, } report_xml() @@ -251,14 +251,14 @@ class act_window(osv.osv): } _defaults = { - 'type': lambda *a: 'ir.actions.act_window', - 'view_type': lambda *a: 'form', - 'view_mode': lambda *a: 'tree,form', - 'context': lambda *a: '{}', - 'limit': lambda *a: 80, - 'target': lambda *a: 'current', - 'auto_refresh': lambda *a: 0, - 'auto_search':lambda *a: True, + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'tree,form', + 'context': '{}', + 'limit': 80, + 'target': 'current', + 'auto_refresh': 0, + 'auto_search':True, 'multi': False, } @@ -298,7 +298,7 @@ class act_window_view(osv.osv): help="If set to true, the action will not be displayed on the right toolbar of a form view."), } _defaults = { - 'multi': lambda *a: False, + 'multi': False, } def _auto_init(self, cr, context=None): super(act_window_view, self)._auto_init(cr, context) @@ -322,8 +322,8 @@ class act_wizard(osv.osv): 'model': fields.char('Object', size=64), } _defaults = { - 'type': lambda *a: 'ir.actions.wizard', - 'multi': lambda *a: False, + 'type': 'ir.actions.wizard', + 'multi': False, } act_wizard() @@ -344,8 +344,8 @@ class act_url(osv.osv): ) } _defaults = { - 'type': lambda *a: 'ir.actions.act_url', - 'target': lambda *a: 'new' + 'type': 'ir.actions.act_url', + 'target': 'new' } act_url() @@ -388,7 +388,7 @@ class server_object_lines(osv.osv): ], 'Type', required=True, size=32, change_default=True), } _defaults = { - 'type': lambda *a: 'equation', + 'type': 'equation', } server_object_lines() @@ -490,11 +490,11 @@ class actions_server(osv.osv): 'copy_object': fields.reference('Copy Of', selection=_select_objects, size=256), } _defaults = { - 'state': lambda *a: 'dummy', - 'condition': lambda *a: 'True', - 'type': lambda *a: 'ir.actions.server', - 'sequence': lambda *a: 5, - 'code': lambda *a: """# You can use the following variables: + 'state': 'dummy', + 'condition': 'True', + 'type': 'ir.actions.server', + 'sequence': 5, + 'code': """# You can use the following variables: # - self: ORM model of the record on which the action is triggered # - object: browse_record of the record on which the action is triggered if there is one, otherwise None # - pool: ORM model pool (i.e. self.pool) @@ -747,7 +747,7 @@ class act_window_close(osv.osv): _inherit = 'ir.actions.actions' _table = 'ir_actions' _defaults = { - 'type': lambda *a: 'ir.actions.act_window_close', + 'type': 'ir.actions.act_window_close', } act_window_close() diff --git a/openerp/addons/base/ir/ir_cron.py b/openerp/addons/base/ir/ir_cron.py index dbc89278ece..243f4c772ea 100644 --- a/openerp/addons/base/ir/ir_cron.py +++ b/openerp/addons/base/ir/ir_cron.py @@ -80,13 +80,13 @@ class ir_cron(osv.osv): _defaults = { 'nextcall' : lambda *a: time.strftime(DEFAULT_SERVER_DATETIME_FORMAT), - 'priority' : lambda *a: 5, + 'priority' : 5, 'user_id' : lambda obj,cr,uid,context: uid, - 'interval_number' : lambda *a: 1, - 'interval_type' : lambda *a: 'months', - 'numbercall' : lambda *a: 1, - 'active' : lambda *a: 1, - 'doall' : lambda *a: 1 + 'interval_number' : 1, + 'interval_type' : 'months', + 'numbercall' : 1, + 'active' : 1, + 'doall' : 1 } def _check_args(self, cr, uid, ids, context=None): diff --git a/openerp/addons/base/ir/ir_mail_server.py b/openerp/addons/base/ir/ir_mail_server.py index 6099c68a0fb..1f5c14209a9 100644 --- a/openerp/addons/base/ir/ir_mail_server.py +++ b/openerp/addons/base/ir/ir_mail_server.py @@ -197,7 +197,7 @@ class ir_mail_server(osv.osv): logpiper = WriteToLogger(_logger) smtplib.stderr = logpiper smtplib.stdout = logpiper - return super(ir_mail_server, self).__init__(*args,**kwargs) + super(ir_mail_server, self).__init__(*args,**kwargs) def name_get(self, cr, uid, ids, context=None): return [(a["id"], "(%s)" % (a['name'])) for a in self.read(cr, uid, ids, ['name'], context=context)] diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index e477f2f09a5..089eefbb6a0 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -106,7 +106,7 @@ class ir_model(osv.osv): } _defaults = { - 'model': lambda *a: 'x_', + 'model': 'x_', 'state': lambda self,cr,uid,ctx=None: (ctx and ctx.get('manual',False)) and 'manual' or 'base', } diff --git a/openerp/addons/base/ir/ir_ui_menu.py b/openerp/addons/base/ir/ir_ui_menu.py index 5ab546cb554..43ece8c0868 100644 --- a/openerp/addons/base/ir/ir_ui_menu.py +++ b/openerp/addons/base/ir/ir_ui_menu.py @@ -132,20 +132,29 @@ class ir_ui_menu(osv.osv): return len(result) return result - def _get_full_name(self, cr, uid, ids, name, args, context): - res = {} - for m in self.browse(cr, uid, ids, context=context): - res[m.id] = self._get_one_full_name(m) + def name_get(self, cr, uid, ids, context=None): + res = [] + for id in ids: + elmt = self.browse(cr, uid, id, context=context) + res.append((id, self._get_one_full_name(elmt))) return res - def _get_one_full_name(self, menu, level=6): + def _get_full_name(self, cr, uid, ids, name=None, args=None, context=None): + if context == None: + context = {} + res = {} + for elmt in self.browse(cr, uid, ids, context=context): + res[elmt.id] = self._get_one_full_name(elmt) + return res + + def _get_one_full_name(self, elmt, level=6): if level<=0: return '...' - if menu.parent_id: - parent_path = self._get_one_full_name(menu.parent_id, level-1) + "/" + if elmt.parent_id: + parent_path = self._get_one_full_name(elmt.parent_id, level-1) + "/" else: parent_path = '' - return parent_path + menu.name + return parent_path + elmt.name def create(self, *args, **kwargs): self.clear_cache() @@ -282,7 +291,7 @@ class ir_ui_menu(osv.osv): 'groups_id': fields.many2many('res.groups', 'ir_ui_menu_group_rel', 'menu_id', 'gid', 'Groups', help="If you have groups, the visibility of this menu will be based on these groups. "\ "If this field is empty, OpenERP will compute visibility based on the related object's read access."), - 'complete_name': fields.function(_get_full_name, + 'complete_name': fields.function(_get_full_name, string='Full Path', type='char', size=128), 'icon': fields.selection(tools.icons, 'Icon', size=64), 'icon_pict': fields.function(_get_icon_pict, type='char', size=32), diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index 868f634783c..2f2a610877d 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -300,7 +300,7 @@ class view_sc(osv.osv): _order = 'sequence,name' _defaults = { - 'resource': lambda *a: 'ir.ui.menu', + 'resource': 'ir.ui.menu', 'user_id': lambda obj, cr, uid, context: uid, } _sql_constraints = [ diff --git a/openerp/addons/base/module/module_view.xml b/openerp/addons/base/module/module_view.xml index c3b3684f07c..1ec76ec0988 100644 --- a/openerp/addons/base/module/module_view.xml +++ b/openerp/addons/base/module/module_view.xml @@ -105,7 +105,7 @@ ir.module.module.form ir.module.module -
+
@@ -172,6 +172,7 @@ + diff --git a/openerp/addons/base/module/wizard/base_module_upgrade.py b/openerp/addons/base/module/wizard/base_module_upgrade.py index 04b7e785e48..bd6b9b7640d 100644 --- a/openerp/addons/base/module/wizard/base_module_upgrade.py +++ b/openerp/addons/base/module/wizard/base_module_upgrade.py @@ -46,12 +46,12 @@ class base_module_upgrade(osv.osv_memory): ids = self.get_module_list(cr, uid, context=context) if not ids: - res['arch'] = ''' -
-
- + res['arch'] = ''' + +
+
''' return res diff --git a/openerp/addons/base/res/__init__.py b/openerp/addons/base/res/__init__.py index 10bd4e89abd..e8adecc1d1a 100644 --- a/openerp/addons/base/res/__init__.py +++ b/openerp/addons/base/res/__init__.py @@ -31,7 +31,6 @@ import res_company import res_users import res_request import res_lang -import res_widget import ir_property import report diff --git a/openerp/addons/base/res/res_bank.py b/openerp/addons/base/res/res_bank.py index 3d6fce8113a..5dec91990b4 100644 --- a/openerp/addons/base/res/res_bank.py +++ b/openerp/addons/base/res/res_bank.py @@ -155,7 +155,7 @@ class res_partner_bank(osv.osv): cursor, user, 'country_id', context=context), 'state_id': lambda obj, cursor, user, context: obj._default_value( cursor, user, 'state_id', context=context), - 'name': lambda *args: '/' + 'name': '/' } def fields_get(self, cr, uid, fields=None, context=None): diff --git a/openerp/addons/base/res/res_company.py b/openerp/addons/base/res/res_company.py index e371bd1f9db..5732546ae24 100644 --- a/openerp/addons/base/res/res_company.py +++ b/openerp/addons/base/res/res_company.py @@ -51,8 +51,8 @@ class multi_company_default(osv.osv): } _defaults = { - 'expression': lambda *a: 'True', - 'sequence': lambda *a: 100, + 'expression': 'True', + 'sequence': 100, } def copy(self, cr, uid, id, default=None, context=None): diff --git a/openerp/addons/base/res/res_company_view.xml b/openerp/addons/base/res/res_company_view.xml index b8cb12d3dd0..24f79efde79 100644 --- a/openerp/addons/base/res/res_company_view.xml +++ b/openerp/addons/base/res/res_company_view.xml @@ -108,6 +108,14 @@
+ + Companies + ir.actions.act_window + res.company + form + tree,form + [('id','=',active_id)] + Companies ir.actions.act_window @@ -125,6 +133,13 @@ + + + + Companies + + + multi_company.default.tree multi_company.default diff --git a/openerp/addons/base/res/res_config.py b/openerp/addons/base/res/res_config.py index c24fc11a377..1aa108c14d2 100644 --- a/openerp/addons/base/res/res_config.py +++ b/openerp/addons/base/res/res_config.py @@ -361,6 +361,7 @@ class res_config_installer(osv.osv_memory): 'to install', ['uninstalled'], context=context) cr.commit() #TOFIX: after remove this statement, installation wizard is fail new_db, self.pool = pooler.restart_pool(cr.dbname, update_module=True) + res_config_installer() DEPRECATION_MESSAGE = 'You are using an addon using old-style configuration '\ @@ -538,6 +539,10 @@ class res_config_settings(osv.osv_memory): ir_module.button_uninstall(cr, uid, to_uninstall_ids, context=context) ir_module.button_immediate_install(cr, uid, to_install_ids, context=context) + config = self.pool.get('res.config').next(cr, uid, [], context=context) or {} + if config.get('type') not in ('ir.actions.act_window_close',): + return config + # force client-side reload (update user menu and current view) return { 'type': 'ir.actions.client', diff --git a/openerp/addons/base/res/res_country.py b/openerp/addons/base/res/res_country.py index 35fb2a29ea7..98a3b769a11 100644 --- a/openerp/addons/base/res/res_country.py +++ b/openerp/addons/base/res/res_country.py @@ -47,7 +47,7 @@ class Country(osv.osv): help='The full name of the country.', required=True, translate=True), 'code': fields.char('Country Code', size=2, help='The ISO country code in two chars.\n' - 'You can use this field for quick search.', required=True), + 'You can use this field for quick search.'), 'address_format': fields.text('Address Format', help="""You can state here the usual format to use for the \ addresses belonging to this country.\n\nYou can use the python-style string patern with all the field of the address \ (for example, use '%(street)s' to display the field 'street') plus diff --git a/openerp/addons/base/res/res_country_view.xml b/openerp/addons/base/res/res_country_view.xml index 47b665426f9..8f64d330440 100644 --- a/openerp/addons/base/res/res_country_view.xml +++ b/openerp/addons/base/res/res_country_view.xml @@ -31,8 +31,7 @@ - diff --git a/openerp/addons/base/res/res_currency.py b/openerp/addons/base/res/res_currency.py index 10a0b56b68c..fa69919af24 100644 --- a/openerp/addons/base/res/res_currency.py +++ b/openerp/addons/base/res/res_currency.py @@ -69,7 +69,7 @@ class res_currency(osv.osv): 'position': fields.selection([('after','After Amount'),('before','Before Amount')], 'Symbol Position', help="Determines where the currency symbol should be placed after or before the amount.") } _defaults = { - 'active': lambda *a: 1, + 'active': 1, 'position' : 'after', 'rounding': 0.01, 'accuracy': 4, diff --git a/openerp/addons/base/res/res_lang.py b/openerp/addons/base/res/res_lang.py index 2b135a6f34a..6c62877a89a 100644 --- a/openerp/addons/base/res/res_lang.py +++ b/openerp/addons/base/res/res_lang.py @@ -143,14 +143,14 @@ class lang(osv.osv): 'thousands_sep':fields.char('Thousands Separator',size=64), } _defaults = { - 'active': lambda *a: 1, - 'translatable': lambda *a: 0, - 'direction': lambda *a: 'ltr', + 'active': 1, + 'translatable': 0, + 'direction': 'ltr', 'date_format':_get_default_date_format, 'time_format':_get_default_time_format, - 'grouping':lambda *a: '[]', - 'decimal_point':lambda *a: '.', - 'thousands_sep':lambda *a: ',', + 'grouping': '[]', + 'decimal_point': '.', + 'thousands_sep': ',', } _sql_constraints = [ ('name_uniq', 'unique (name)', 'The name of the language must be unique !'), diff --git a/openerp/addons/base/res/res_partner.py b/openerp/addons/base/res/res_partner.py index 9ed2333a23b..283d8add899 100644 --- a/openerp/addons/base/res/res_partner.py +++ b/openerp/addons/base/res/res_partner.py @@ -135,7 +135,7 @@ class res_partner_category(osv.osv): (osv.osv._check_recursion, 'Error ! You can not create recursive categories.', ['parent_id']) ] _defaults = { - 'active': lambda *a: 1, + 'active': 1, } _parent_store = True _parent_order = 'name' @@ -320,6 +320,12 @@ class res_partner(osv.osv, format_address): return {'value': dict((key, value_or_id(parent[key])) for key in ADDRESS_FIELDS)} return {} + def onchange_state(self, cr, uid, ids, state_id, context=None): + if state_id: + country_id = self.pool.get('res.country.state').browse(cr, uid, state_id, context).country_id.id + return {'value':{'country_id':country_id}} + return {} + def _check_ean_key(self, cr, uid, ids, context=None): for partner_o in pooler.get_pool(cr.dbname).get('res.partner').read(cr, uid, ids, ['ean13',]): thisean=partner_o['ean13'] diff --git a/openerp/addons/base/res/res_partner_view.xml b/openerp/addons/base/res/res_partner_view.xml index 963262556be..bd379e3bec2 100644 --- a/openerp/addons/base/res/res_partner_view.xml +++ b/openerp/addons/base/res/res_partner_view.xml @@ -162,7 +162,7 @@
- +
diff --git a/openerp/addons/base/res/res_request.py b/openerp/addons/base/res/res_request.py index 3b576c84162..b1e3bf88505 100644 --- a/openerp/addons/base/res/res_request.py +++ b/openerp/addons/base/res/res_request.py @@ -77,10 +77,10 @@ class res_request(osv.osv): 'history': fields.one2many('res.request.history','req_id', 'History') } _defaults = { - 'act_from': lambda obj,cr,uid,context={}: uid, - 'state': lambda obj,cr,uid,context={}: 'draft', - 'active': lambda obj,cr,uid,context={}: True, - 'priority': lambda obj,cr,uid,context={}: '1', + 'act_from': lambda obj,cr,uid,context=None: uid, + 'state': 'draft', + 'active': True, + 'priority': '1', } _order = 'priority desc, trigger_date, create_date desc' _table = 'res_request' @@ -94,7 +94,7 @@ class res_request_link(osv.osv): 'priority': fields.integer('Priority'), } _defaults = { - 'priority': lambda *a: 5, + 'priority': 5, } _order = 'priority' res_request_link() @@ -110,9 +110,9 @@ class res_request_history(osv.osv): 'date_sent': fields.datetime('Date sent', states={'waiting':[('readonly',True)]}, required=True) } _defaults = { - 'name': lambda *a: 'NoName', - 'act_from': lambda obj,cr,uid,context={}: uid, - 'act_to': lambda obj,cr,uid,context={}: uid, + 'name': 'NoName', + 'act_from': lambda obj,cr,uid,context=None: uid, + 'act_to': lambda obj,cr,uid,context=None: uid, 'date_sent': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), } res_request_history() diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index 27fb7603c7e..f272b3712c6 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -122,7 +122,6 @@ class res_users(osv.osv): } _name = "res.users" _description = 'Users' - _order = 'login' def _set_new_password(self, cr, uid, id, name, value, args, context=None): if value is False: diff --git a/openerp/addons/base/res/res_widget.py b/openerp/addons/base/res/res_widget.py deleted file mode 100644 index 2137eab51fd..00000000000 --- a/openerp/addons/base/res/res_widget.py +++ /dev/null @@ -1,89 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -from osv import fields,osv - - -class res_widget(osv.osv): - _name = "res.widget" - _rec_name = "title" - _columns = { - 'title' : fields.char('Title', size=64, required=True, translate=True), - 'content': fields.text('Content', required=True), - } - -res_widget() - - -class res_widget_user(osv.osv): - _name="res.widget.user" - _rec_name="user_id" - _order = "sequence" - _columns = { - 'sequence': fields.integer('Sequence'), - 'user_id': fields.many2one('res.users','User', select=1, ondelete='cascade'), - 'widget_id': fields.many2one('res.widget','Widget',required=True, ondelete='cascade'), - } - - def create(self, cr, uid, vals, context=None): - existing = self.search(cr, uid, [('user_id', '=', vals.get('user_id')), ('widget_id', '=', vals.get('widget_id'))], context=context) - if existing: - res = existing[0] - else: - res = super(res_widget_user, self).create(cr, uid, vals, context=context) - return res - -res_widget_user() - -class res_widget_wizard(osv.osv_memory): - _name = "res.widget.wizard" - _description = "Add a widget for User" - - def widgets_list_get(self, cr, uid,context=None): - widget_obj=self.pool.get('res.widget') - ids=widget_obj.search(cr, uid,[],context=context) - if not len(ids): - return [] - reads = widget_obj.read(cr, uid, ids, ['title'], context=context) - res = [] - for record in reads: - res.append((record['id'], record['title'])) - return res - - _columns = { - 'widgets_list': fields.selection(widgets_list_get,string='Widget',required=True), - } - - def action_get(self, cr, uid, context=None): - return self.pool.get('ir.actions.act_window').for_xml_id( - cr, uid, 'base', 'action_res_widget_wizard', context=context) - - def res_widget_add(self, cr, uid, ids, context=None): - widget_id = self.read(cr, uid, ids, context=context)[0] - if widget_id.has_key('widgets_list') and widget_id['widgets_list']: - self.pool.get('res.widget.user').create( - cr, uid, {'user_id':uid, 'widget_id':widget_id['widgets_list']}, context=context) - return {'type': 'ir.actions.act_window_close'} - -res_widget_wizard() - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/res/res_widget_data.xml b/openerp/addons/base/res/res_widget_data.xml deleted file mode 100644 index 48d53c7a021..00000000000 --- a/openerp/addons/base/res/res_widget_data.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - OpenERP Tweets - -]]> - - - - Events - -
]]> - - - - Facebook - - ]]> - - - - Notes - - ]]> - - - - Google Maps - - ]]> - - - - Currency Converter - - ]]> - - - - - - - diff --git a/openerp/addons/base/res/res_widget_demo.xml b/openerp/addons/base/res/res_widget_demo.xml deleted file mode 100644 index 24e7a133ed9..00000000000 --- a/openerp/addons/base/res/res_widget_demo.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/openerp/addons/base/res/res_widget_view.xml b/openerp/addons/base/res/res_widget_view.xml deleted file mode 100644 index bad582f97db..00000000000 --- a/openerp/addons/base/res/res_widget_view.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - - - res.widget.search - res.widget - - - - - - - - res.widget.form - res.widget - -
- - - - - - -
-
-
- - res.widget.tree - res.widget - - - - - - - - - Homepage Widgets - res.widget - form - tree,form - - - - - - res.widget.user.tree - res.widget.user - - - - - - - - - - res.widget.user.form - res.widget.user - -
- - - - - - - -
-
-
- - Widgets per User - res.widget.user - form - tree,form - - - - - Homepage Widgets Management - res.widget.wizard - -
-
-
- - - -
-
-
- -
-
diff --git a/openerp/addons/base/security/base_security.xml b/openerp/addons/base/security/base_security.xml index 02323a635df..b0de06078af 100644 --- a/openerp/addons/base/security/base_security.xml +++ b/openerp/addons/base/security/base_security.xml @@ -46,12 +46,6 @@ - - res.widget.user rule - - ['|', ('user_id','=',user.id),('user_id','=',False)] - - res.partner company diff --git a/openerp/addons/base/security/ir.model.access.csv b/openerp/addons/base/security/ir.model.access.csv index 8e9134ff070..35d5b82bc41 100644 --- a/openerp/addons/base/security/ir.model.access.csv +++ b/openerp/addons/base/security/ir.model.access.csv @@ -1,6 +1,4 @@ "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" -"access_res_widget_user_all","res_widget_user all","model_res_widget_user",,1,1,1,1 -"access_res_widget_user_group_user","res_widget_user group_user","model_res_widget_user","group_user",1,1,1,1 "access_ir_attachment_all","ir_attachment all","model_ir_attachment",,1,0,0,0 "access_ir_attachment_group_user","ir_attachment group_user","model_ir_attachment","group_user",1,1,1,1 "access_ir_cron_group_cron","ir_cron group_cron","model_ir_cron","group_system",1,1,1,1 @@ -115,8 +113,6 @@ "access_ir_filter all","ir_filters all","model_ir_filters",,1,0,0,0 "access_ir_filter employee","ir_filters employee","model_ir_filters","group_user",1,1,1,1 "access_ir_filters","ir_filters_all","model_ir_filters",,1,1,1,1 -"access_res_widget","res.widget","model_res_widget","group_erp_manager",1,1,1,1 -"access_res_widget_user","res.widget.user","model_res_widget",,1,0,0,0 "access_ir_config_parameter","ir_config_parameter","model_ir_config_parameter",,1,0,0,0 "access_ir_mail_server_all","ir_mail_server","model_ir_mail_server",,1,0,0,0 "access_ir_actions_client","ir_actions_client all","model_ir_actions_client",,1,0,0,0 diff --git a/openerp/addons/base/tests/__init__.py b/openerp/addons/base/tests/__init__.py index 42fef2eb39d..409f9928c6f 100644 --- a/openerp/addons/base/tests/__init__.py +++ b/openerp/addons/base/tests/__init__.py @@ -1,5 +1,7 @@ -import test_ir_values, test_base +import test_base, test_expression, test_ir_values checks = [ - test_ir_values, test_base + test_base, + test_expression, + test_ir_values, ] diff --git a/openerp/addons/base/tests/test_expression.py b/openerp/addons/base/tests/test_expression.py new file mode 100644 index 00000000000..5690cff443a --- /dev/null +++ b/openerp/addons/base/tests/test_expression.py @@ -0,0 +1,72 @@ +import unittest2 + +import openerp.tests.common as common + +class test_expression(common.TransactionCase): + + def test_in_not_in_m2m(self): + + registry, cr, uid = self.registry, self.cr, self.uid + + # Create 4 partners with no category, or one or two categories (out of two categories). + + categories = registry('res.partner.category') + cat_a = categories.create(cr, uid, {'name': 'test_expression_category_A'}) + cat_b = categories.create(cr, uid, {'name': 'test_expression_category_B'}) + + partners = registry('res.partner') + a = partners.create(cr, uid, {'name': 'test_expression_partner_A', 'category_id': [(6, 0, [cat_a])]}) + b = partners.create(cr, uid, {'name': 'test_expression_partner_B', 'category_id': [(6, 0, [cat_b])]}) + ab = partners.create(cr, uid, {'name': 'test_expression_partner_AB', 'category_id': [(6, 0, [cat_a, cat_b])]}) + c = partners.create(cr, uid, {'name': 'test_expression_partner_C'}) + + # The tests. + + # On a one2many or many2many field, `in` should be read `contains` (and + # `not in` should be read `doesn't contain`. + + with_a = partners.search(cr, uid, [('category_id', 'in', [cat_a])]) + self.assertEqual(set([a, ab]), set(with_a), "Search for category_id in cat_a failed.") + + with_b = partners.search(cr, uid, [('category_id', 'in', [cat_b])]) + self.assertEqual(set([ab, b]), set(with_b), "Search for category_id in cat_b failed.") + + # Partners with the category A or the category B. + with_a_or_b = partners.search(cr, uid, [('category_id', 'in', [cat_a, cat_b])]) + self.assertEqual(set([ab, a, b]), set(with_a_or_b), "Search for category_id contains cat_a or cat_b failed.") + + # Show that `contains list` is really `contains element or contains element`. + with_a_or_with_b = partners.search(cr, uid, ['|', ('category_id', 'in', [cat_a]), ('category_id', 'in', [cat_b])]) + self.assertEqual(set([ab, a, b]), set(with_a_or_with_b), "Search for category_id contains cat_a or contains cat_b failed.") + + # If we change the OR in AND... + with_a_and_b = partners.search(cr, uid, [('category_id', 'in', [cat_a]), ('category_id', 'in', [cat_b])]) + self.assertEqual(set([ab]), set(with_a_and_b), "Search for category_id contains cat_a and cat_b failed.") + + # Partners without category A and without category B. + without_a_or_b = partners.search(cr, uid, [('category_id', 'not in', [cat_a, cat_b])]) + self.assertTrue(all(i not in without_a_or_b for i in [a, b, ab]), "Search for category_id doesn't contain cat_a or cat_b failed (1).") + self.assertTrue(c in without_a_or_b, "Search for category_id doesn't contain cat_a or cat_b failed (2).") + + # Show that `doesn't contain list` is really `doesn't contain element and doesn't contain element`. + without_a_and_without_b = partners.search(cr, uid, [('category_id', 'not in', [cat_a]), ('category_id', 'not in', [cat_b])]) + self.assertTrue(all(i not in without_a_and_without_b for i in [a, b, ab]), "Search for category_id doesn't contain cat_a and cat_b failed (1).") + self.assertTrue(c in without_a_and_without_b, "Search for category_id doesn't contain cat_a and cat_b failed (2).") + + # We can exclude any partner containing the category A. + without_a = partners.search(cr, uid, [('category_id', 'not in', [cat_a])]) + self.assertTrue(a not in without_a, "Search for category_id doesn't contain cat_a failed (1).") + self.assertTrue(ab not in without_a, "Search for category_id doesn't contain cat_a failed (2).") + self.assertTrue(set([b, c]).issubset(set(without_a)), "Search for category_id doesn't contain cat_a failed (3).") + + # (Obviously we can do the same for cateory B.) + without_b = partners.search(cr, uid, [('category_id', 'not in', [cat_b])]) + self.assertTrue(b not in without_b, "Search for category_id doesn't contain cat_b failed (1).") + self.assertTrue(ab not in without_b, "Search for category_id doesn't contain cat_b failed (2).") + self.assertTrue(set([a, c]).issubset(set(without_b)), "Search for category_id doesn't contain cat_b failed (3).") + + # We can't express the following: Partners with a category different than A. + # with_any_other_than_a = ... + # self.assertTrue(a not in with_any_other_than_a, "Search for category_id with any other than cat_a failed (1).") + # self.assertTrue(ab in with_any_other_than_a, "Search for category_id with any other than cat_a failed (2).") + diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 547889075fb..8d83e1058bc 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -1548,7 +1548,6 @@ class BaseModel(object): ) self._invalids.update(fields) if error_msgs: - cr.rollback() raise except_orm('ValidateError', '\n'.join(error_msgs)) else: self._invalids.clear() diff --git a/openerp/tests/__init__.py b/openerp/tests/__init__.py index 3427743263c..aa39b777c0f 100644 --- a/openerp/tests/__init__.py +++ b/openerp/tests/__init__.py @@ -9,6 +9,7 @@ See the :ref:`test-framework` section in the :ref:`features` list. """ from . import test_expression, test_html_sanitize, test_ir_sequence, test_orm,\ + test_basecase, \ test_view_validation, test_uninstall, test_misc, test_db_cursor fast_suite = [ @@ -20,6 +21,7 @@ checks = [ test_html_sanitize, test_db_cursor, test_orm, + test_basecase, test_view_validation, test_misc, ] diff --git a/openerp/tests/common.py b/openerp/tests/common.py index 53c67c68844..3cc8b126c02 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- -import os +""" +The module :mod:`openerp.tests.common` provides a few helpers and classes to write +tests. +""" import threading import time import unittest2 @@ -40,10 +43,49 @@ def stop_openerp(): """ openerp.service.stop_services() -class TransactionCase(unittest2.TestCase): +class BaseCase(unittest2.TestCase): """ - Subclass of TestCase with a single transaction, rolled-back at the end of - the tests. + Subclass of TestCase for common OpenERP-specific code. + + This class is abstract and expects self.cr and self.uid to be initialized by subclasses. + """ + + @classmethod + def cursor(self): + return openerp.modules.registry.RegistryManager.get(DB).db.cursor() + + @classmethod + def registry(self, model): + return openerp.modules.registry.RegistryManager.get(DB)[model] + + @classmethod + def ref(self, xid): + """ Returns database ID corresponding to a given identifier. + + :param xid: fully-qualified record identifier, in the form ``module.identifier`` + :raise: ValueError if not found + """ + assert "." in xid, "this method requires a fully qualified parameter, in the following form: 'module.identifier'" + module, xid = xid.split('.') + _, id = self.registry('ir.model.data').get_object_reference(self.cr, self.uid, module, xid) + return id + + @classmethod + def browse_ref(self, xid): + """ Returns a browsable record for the given identifier. + + :param xid: fully-qualified record identifier, in the form ``module.identifier`` + :raise: ValueError if not found + """ + assert "." in xid, "this method requires a fully qualified parameter, in the following form: 'module.identifier'" + module, xid = xid.split('.') + return self.registry('ir.model.data').get_object(self.cr, self.uid, module, xid) + + +class TransactionCase(BaseCase): + """ + Subclass of BaseCase with a single transaction, rolled-back at the end of + each test (method). """ def setUp(self): @@ -54,19 +96,31 @@ class TransactionCase(unittest2.TestCase): self.cr.rollback() self.cr.close() - def cursor(self): - return openerp.modules.registry.RegistryManager.get(DB).db.cursor() - def registry(self, model): - return openerp.modules.registry.RegistryManager.get(DB)[model] +class SingleTransactionCase(BaseCase): + """ + Subclass of BaseCase with a single transaction for the whole class, + rolled-back after all the tests. + """ + + @classmethod + def setUpClass(cls): + cls.cr = cls.cursor() + cls.uid = openerp.SUPERUSER_ID + + @classmethod + def tearDownClass(cls): + cls.cr.rollback() + cls.cr.close() + class RpcCase(unittest2.TestCase): """ Subclass of TestCase with a few XML-RPC proxies. """ - def __init__(self, name): - super(RpcCase, self).__init__(name) + def __init__(self, methodName='runTest'): + super(RpcCase, self).__init__(methodName) class A(object): pass diff --git a/openerp/tests/test_basecase.py b/openerp/tests/test_basecase.py new file mode 100644 index 00000000000..55125b6d7c2 --- /dev/null +++ b/openerp/tests/test_basecase.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +import unittest2 + +import common + +class test_single_transaction_case(common.SingleTransactionCase): + """ + Check the whole-class transaction behavior of SingleTransactionCase. + """ + + def test_00(self): + """Create a partner.""" + cr, uid = self.cr, self.uid + self.registry('res.partner').create(cr, uid, {'name': 'test_per_class_teardown_partner'}) + ids = self.registry('res.partner').search(cr, uid, [('name', '=', 'test_per_class_teardown_partner')]) + self.assertEqual(1, len(ids), "Test partner not found.") + + def test_01(self): + """Find the created partner.""" + cr, uid = self.cr, self.uid + ids = self.registry('res.partner').search(cr, uid, [('name', '=', 'test_per_class_teardown_partner')]) + self.assertEqual(1, len(ids), "Test partner not found.") + + def test_20a(self): + """ Create a partner with a XML ID """ + cr, uid = self.cr, self.uid + res_partner = self.registry('res.partner') + ir_model_data = self.registry('ir.model.data') + pid, _ = res_partner.name_create(cr, uid, 'Mr Blue') + ir_model_data.create(cr, uid, {'name': 'test_partner_blue', + 'module': 'base', + 'model': 'res.partner', + 'res_id': pid}) + def test_20b(self): + """ Resolve xml id with ref() and browse_ref() """ + cr, uid = self.cr, self.uid + res_partner = self.registry('res.partner') + xid = 'base.test_partner_blue' + p_ref = self.ref(xid) + self.assertTrue(p_ref, "ref() should resolve xid to database ID") + partner = res_partner.browse(cr, uid, p_ref) + p_browse_ref = self.browse_ref(xid) + self.assertEqual(partner, p_browse_ref, "browse_ref() should resolve xid to browse records") + + + +class test_transaction_case(common.TransactionCase): + """ + Check the per-method transaction behavior of TransactionCase. + """ + + def test_00(self): + """Create a partner.""" + cr, uid = self.cr, self.uid + ids = self.registry('res.partner').search(cr, uid, [('name', '=', 'test_per_class_teardown_partner')]) + self.assertEqual(0, len(ids), "Test partner found.") + self.registry('res.partner').create(cr, uid, {'name': 'test_per_class_teardown_partner'}) + ids = self.registry('res.partner').search(cr, uid, [('name', '=', 'test_per_class_teardown_partner')]) + self.assertEqual(1, len(ids), "Test partner not found.") + + def test_01(self): + """Don't find the created partner.""" + cr, uid = self.cr, self.uid + ids = self.registry('res.partner').search(cr, uid, [('name', '=', 'test_per_class_teardown_partner')]) + self.assertEqual(0, len(ids), "Test partner found.") + +if __name__ == '__main__': + unittest2.main() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tools/yaml_import.py b/openerp/tools/yaml_import.py index 501ab30d879..ca7ab92a225 100644 --- a/openerp/tools/yaml_import.py +++ b/openerp/tools/yaml_import.py @@ -286,8 +286,11 @@ class YamlInterpreter(object): model = self.get_model(record.model) view_id = record.view - if view_id and (view_id is not True): - view_id = self.pool.get('ir.model.data').get_object_reference(self.cr, SUPERUSER_ID, self.module, record.view)[1] + if view_id and (view_id is not True) and isinstance(view_id, basestring): + module = self.module + if '.' in view_id: + module, view_id = view_id.split('.',1) + view_id = self.pool.get('ir.model.data').get_object_reference(self.cr, SUPERUSER_ID, module, view_id)[1] if model.is_transient(): record_dict=self.create_osv_memory_record(record, fields) @@ -378,7 +381,11 @@ class YamlInterpreter(object): return False return val - view = view_info and etree.fromstring(view_info['arch'].encode('utf-8')) or False + if view_info: + arch = etree.fromstring(view_info['arch'].encode('utf-8')) + view = arch if len(arch) else False + else: + view = False fields = fields or {} if view is not False: fg = view_info['fields'] diff --git a/openerp/tools/yaml_tag.py b/openerp/tools/yaml_tag.py index aca802c374a..b22787ddf98 100644 --- a/openerp/tools/yaml_tag.py +++ b/openerp/tools/yaml_tag.py @@ -109,6 +109,8 @@ def assert_constructor(loader, node): def record_constructor(loader, node): kwargs = loader.construct_mapping(node) + assert "model" in kwargs, "'model' argument is required for !record" + assert "id" in kwargs, "'id' argument is required for !record" return Record(**kwargs) def python_constructor(loader, node):