summaryrefslogtreecommitdiff
path: root/addons/base_module_quality
diff options
context:
space:
mode:
authorpso (tiny) <pso@tinyerp.com>2009-01-10 10:42:34 +0530
committerpso (tiny) <pso@tinyerp.com>2009-01-10 10:42:34 +0530
commit83e61feae306e297d6a74e6f918e2982da4e10d7 (patch)
tree967547d3644e52a57700edda93aa68e763bbb95c /addons/base_module_quality
parent9eae2d59410f4d4d0cf1e2d16ca09286fe8616b5 (diff)
parent123f3119bac13d4c21a541afefe2cadf90c8ae98 (diff)
merge
bzr revid: pso@tinyerp.com-20090106113354-lt0txytytk74qjzj bzr revid: pso@tinyerp.com-20090107062356-yv3wq40u2e91aw14 bzr revid: pso@tinyerp.com-20090110051234-v7q0qg7t2858t5tm
Diffstat (limited to 'addons/base_module_quality')
-rw-r--r--addons/base_module_quality/__terp__.py24
-rw-r--r--addons/base_module_quality/base_module_quality.py77
-rw-r--r--addons/base_module_quality/base_module_quality_wizard.xml75
-rw-r--r--addons/base_module_quality/method_test/method_test.py61
-rw-r--r--addons/base_module_quality/pylint_test/pylint_test.py62
-rw-r--r--addons/base_module_quality/pylint_test/pylint_test_config.txt2
-rw-r--r--addons/base_module_quality/speed_test/speed_test.py96
-rw-r--r--addons/base_module_quality/terp_test/terp_test.py100
-rw-r--r--addons/base_module_quality/wizard/module_quality_check.py180
9 files changed, 349 insertions, 328 deletions
diff --git a/addons/base_module_quality/__terp__.py b/addons/base_module_quality/__terp__.py
index 1c056d84771..d77b50cd830 100644
--- a/addons/base_module_quality/__terp__.py
+++ b/addons/base_module_quality/__terp__.py
@@ -19,23 +19,25 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
+
+
{
- "name" : "Base module quality",
- "author" : "Tiny",
- "version" : "1.0",
- "depends" : ["base",],
- "description": """"
+ 'name': 'Base module quality',
+ 'version': '1.0',
+ 'category': 'Tiny Specific Modules/Base module quality',
+ 'description': """"
This module's aim is to check the quality of other modules.
It defines a wizard on the list of modules in OpenERP, which allow you to evaluate them on different criteria such as: the respect of OpenERP coding standards, the speed efficiency...
This module also provides generic framework to define your own quality test. For further info, coders may take a look into base_module_quality\README.txt
""",
- "init_xml" : [],
- "update_xml" : ["base_module_quality_wizard.xml", "security/ir.model.access.csv",],
- "category" : "Tiny Specific Modules/Base module quality",
- "active": False,
- "installable": True
+ 'author': 'Tiny',
+ 'depends': ['base'],
+ 'init_xml': [],
+ 'update_xml': ['base_module_quality_wizard.xml', 'security/ir.model.access.csv'],
+ 'installable': True,
+ 'active': False,
+ 'certificate': '75119475677',
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/base_module_quality/base_module_quality.py b/addons/base_module_quality/base_module_quality.py
index 0564d7c9066..4590a51dfe3 100644
--- a/addons/base_module_quality/base_module_quality.py
+++ b/addons/base_module_quality/base_module_quality.py
@@ -21,38 +21,29 @@
##############################################################################
import pooler
import os
+import osv
from tools import config
class abstract_quality_check(object):
'''
- This Class provide...
+ This Class provides...
'''
-# #This float have to store the rating of the module.
-# #Used to compute the final score (average of all scores).
-# score = 0.0
-#
-# #This char have to store the result.
-# #Used to display the result of the test.
-# result = ""
-#
-# #This char have to store the result with more details.
-# #Used to provide more details if necessary.
-# result_details = ""
-#
-# #This bool defines if the test can be run only if the module is installed.
-# #True => the module have to be installed.
-# #False => the module can be uninstalled.
-# bool_installed_only = True
-
def __init__(self):
'''
this method should initialize the var
'''
#This float have to store the rating of the module.
#Used to compute the final score (average of all scores).
+ #0 <= self.score <= 1
self.score = 0.0
+ #This char have to store the name of the test.
+ self.name = ""
+
+ #This char have to store the aim of the test and eventually a note.
+ self.note = ""
+
#This char have to store the result.
#Used to display the result of the test.
self.result = ""
@@ -66,13 +57,13 @@ class abstract_quality_check(object):
#False => the module can be uninstalled.
self.bool_installed_only = True
-
#This variable is use to make result of test should have more weight (Some tests are more critical than others)
- self.ponderation = 0.0
+ self.ponderation = 1.0
#Specify test got an error on module
self.error = False
+ #The tests have to subscribe itselfs in this list, that contains all the test that have to be performed.
self.tests = []
self.list_folders = os.listdir(config['addons_path']+'/base_module_quality/')
for item in self.list_folders:
@@ -86,11 +77,12 @@ class abstract_quality_check(object):
self.tests.append(x3)
# raise 'Not Implemented'
- def run_test(self, cr, uid, module_path="", module_state=""):
+ def run_test(self, cr, uid, module_path=""):
'''
this method should do the test and fill the score, result and result_details var
'''
-# raise 'Not Implemented'
+
+ raise osv.except_osv(_('Programming Error'), _('Test Is Not Implemented'))
def get_objects(self, cr, uid, module):
# This function returns all object of the given module..
@@ -114,40 +106,19 @@ class abstract_quality_check(object):
result_ids[obj] = ids
return result_ids
- def format_table(self, test='', header=[], data_list=[]):
- res_format = {}
- if test=='method':
- detail = ""
- detail += "\n===Method Test===\n"
- res_format['detail'] = detail
- if not data_list[2]:
- detail += ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-16s \n! %-20s \n! %-16s ') % (header[0].ljust(40), header[1].ljust(16), header[2].ljust(20), header[3].ljust(16))
- for res in data_list[1]:
- detail += ('\n|-\n| %s \n| %s \n| %s \n| %s ') % (res, data_list[1][res][0], data_list[1][res][1], data_list[1][res][2])
- res_format['detail'] = detail + '\n|}'
- res_format['summary'] = data_list[0]
- elif test=='pylint':
- res_format['summary'] = data_list[0]
- res_format['detail'] = data_list[1]
- elif test=='speed':
- detail = ""
- detail += "\n===Speed Test===\n"
- res_format['detail'] = detail
- if not data_list[2]:
- detail += ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n! %-10s \n! %-10s \n! %-10s \n! %-20s') % (header[0].ljust(40), header[1].ljust(10), header[2].ljust(10), header[3].ljust(10), header[4].ljust(10), header[5].ljust(20))
- for data in data_list[1]:
- detail += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (data[0], data[1], data[2], data[3], data[4], data[5])
- res_format['detail'] = detail + '\n|}\n'
- res_format['summary'] = data_list[0]
- elif test=='terp':
- res_format['summary'] = data_list[0]
- res_format['detail'] = data_list[1]
- return res_format
+ def format_table(self, header=[], data_list=[]):
+ detail = ""
+ detail += (header[0]) % tuple(header[1])
+ frow = '\n|-'
+ for i in header[1]:
+ frow += '\n| %s'
+ for key, value in data_list.items():
+ detail += (frow) % tuple(value)
+ detail = detail + '\n|}'
+ return detail
def add_quatation(self, x, y):
return x/y
-
-
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_module_quality/base_module_quality_wizard.xml b/addons/base_module_quality/base_module_quality_wizard.xml
index a61d1f4e980..467e7e7dc24 100644
--- a/addons/base_module_quality/base_module_quality_wizard.xml
+++ b/addons/base_module_quality/base_module_quality_wizard.xml
@@ -3,46 +3,75 @@
<data>
<!--<wizard id="base_module_quality" model="ir.module.module" name="base.module.quality" string="Check the Quality of module"/>-->
- <record id="view_wizard_quality_check" model="ir.ui.view">
+ <record id="view_wizard_quality_check_tree" model="ir.ui.view">
+ <field name="name">Results of Quality Checks</field>
+ <field name="model">wizard.quality.check</field>
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+ <tree string="Result">
+ <field name="name"/>
+ <field name="final_score"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="view_wizard_quality_check_form" model="ir.ui.view">
<field name="name">Results of Quality Checks</field>
<field name="model">wizard.quality.check</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Result">
- <notebook>
- <page string="Verbose detail">
- <field name="verbose_detail" string="Verbose detail" nolabel="1" colspan="4" height="350" width="800"/>
- </page>
- </notebook>
+ <field name="name" readonly="1" search="1"/>
+ <field name="final_score" readonly="1" search="1"/>
+ <separator colspan="4" string="Tests"/>
+ <field name="test_ids" nolabel="1" colspan="4" height="350" width="800" readonly="1"/>
</form>
</field>
</record>
- <record id="view_wizard_quality_detail" model="ir.ui.view">
+ <record id="view_wizard_quality_detail_form" model="ir.ui.view">
<field name="name">Results of Quality Checks with detail</field>
<field name="model">quality.check.detail</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Result">
<notebook>
- <page string="Summary">
- <field name="general_info" widget="text_wiki" nolabel="1" colspan="4" height="350" width="800"/>
- </page>
- <page string="Detail">
- <field name="detail" widget="text_wiki" nolabel="1" colspan="4" height="350" width="800"/>
- </page>
- </notebook>
+ <page string="Summary">
+ <field name="name" readonly="1"/>
+ <field name="score" readonly="1"/>
+ <field name="note" readonly="1" colspan="4"/>
+ <field name="summary" widget="text_wiki" nolabel="1" colspan="4" height="350" width="800" readonly="1"/>
+
+ <field name="ponderation" readonly="1"/>
+ <field name="state" readonly="1"/>
+ </page>
+ <page string="Detail">
+ <field name="detail" widget="html_tag" nolabel="1" colspan="4" readonly="1"/>
+ </page>
+ </notebook>
</form>
</field>
</record>
- <act_window
- id="act_view_wiz_quality_check"
- name="Quality Check"
- res_model="wizard.quality.check"
- src_model="ir.module.module"
- target="new"
- view_mode="form"
- context="{'module_id': active_id}"
- />
+
+ <record id="view_wizard_quality_detail_tree" model="ir.ui.view">
+ <field name="name">Results of Quality Checks with detail</field>
+ <field name="model">quality.check.detail</field>
+ <field name="type">tree</field>
+ <field name="arch" type="xml">
+ <tree string="Result">
+ <field name="name" required="1"/>
+ <field name="state"/>
+ <field name="score" required="1"/>
+ <field name="ponderation"/>
+ </tree>
+ </field>
+ </record>
+
+
+ <wizard string="Quality Check"
+ model="ir.module.module"
+ name="create_quality_check_wiz"
+ id="create_quality_check_id"
+ menu="True"/>
</data>
</openerp>
diff --git a/addons/base_module_quality/method_test/method_test.py b/addons/base_module_quality/method_test/method_test.py
index 38a07c9428b..34841dd41cc 100644
--- a/addons/base_module_quality/method_test/method_test.py
+++ b/addons/base_module_quality/method_test/method_test.py
@@ -20,9 +20,7 @@
#
##############################################################################
-
-import os
-from tools import config
+from tools.translate import _
from base_module_quality import base_module_quality
import pooler
@@ -31,69 +29,56 @@ class quality_test(base_module_quality.abstract_quality_check):
def __init__(self):
super(quality_test, self).__init__()
-# self.result = """
-#===Method Test===:
-#
-#This test checks if the module classes are raising exception when calling basic methods or no.
-#
-#"""
+ self.name = _("Method Test")
+ self.note = _("""
+This test checks if the module classes are raising exception when calling basic methods or not.
+""")
self.bool_installed_only = True
self.ponderation = 1.0
return None
- def run_test(self, cr, uid, module_path, module_state):
+ def run_test(self, cr, uid, module_path):
pool = pooler.get_pool(cr.dbname)
module_name = module_path.split('/')[-1]
obj_list = self.get_objects(cr, uid, module_name)
- result = {}
ok_count = 0
ex_count = 0
+ result_dict = {}
for obj in obj_list:
- temp = []
+ temp = [obj]
try:
res = pool.get(obj).search(cr, uid, [])
- temp.append('Ok')
+ temp.append(_('Ok'))
ok_count += 1
except:
- temp.append('Exception')
+ temp.append(_('Exception'))
ex_count += 1
try:
res1 = pool.get(obj).fields_view_get(cr, uid,)
- temp.append('Ok')
+ temp.append(_('Ok'))
ok_count += 1
except:
- temp.append('Exception')
+ temp.append(_('Exception'))
ex_count += 1
try:
res2 = pool.get(obj).read(cr, uid, [])
- temp.append('Ok')
+ temp.append(_('Ok'))
ok_count += 1
except:
- temp.append('Exception')
+ temp.append(_('Exception'))
ex_count += 1
- result[obj] = temp
-# self.result += ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-16s \n! %-20s \n! %-16s ') % ('Object Name'.ljust(40), 'search()'.ljust(16), 'fields_view_get()'.ljust(20), 'read()'.ljust(16))
- header_list = ['Object Name', 'search()', 'fields_view_get', 'read']
-# for res in result:
-# self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s ') % (res, result[res][0],result[res][1], result[res][2])
-# self.result += '\n|}'
+ result_dict[obj] = temp
self.score = (ok_count + ex_count) and float(ok_count)/float(ok_count + ex_count) or 0.0
- if not self.bool_installed_only or module_state=="installed":
- summary = """
-===Method Test===:
-
-This test checks if the module classes are raising exception when calling basic methods or no.
-
-""" #+ "Score: " + str(self.score) + "/10\n"
- else:
- summary =""" \n===Method Test===:
-
-The module has to be installed before running this test.\n\n """
- header_list = ""
- self.error = True
- self.result = self.format_table(test='method', header=header_list, data_list=[summary,result,self.error])
+ self.result = self.get_result(result_dict)
return None
+ def get_result(self, dict):
+ header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-16s \n! %-20s \n! %-16s ', [_('Object Name'), 'search()', 'fields_view_get()', 'read()'])
+ detail = ""
+ if not self.error:
+ detail += self.format_table(header, dict)
+ return detail
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_module_quality/pylint_test/pylint_test.py b/addons/base_module_quality/pylint_test/pylint_test.py
index 5877dc6ff39..04eef3fa7e1 100644
--- a/addons/base_module_quality/pylint_test/pylint_test.py
+++ b/addons/base_module_quality/pylint_test/pylint_test.py
@@ -23,6 +23,7 @@
import os
from tools import config
+from tools.translate import _
from base_module_quality import base_module_quality
@@ -31,17 +32,15 @@ class quality_test(base_module_quality.abstract_quality_check):
def __init__(self):
super(quality_test, self).__init__()
-# self.result = """
-#===Pylint Test===:
-#
-# This test checks if the module satisfy the current coding standard used by OpenERP.
-#
-#"""
+ self.name = _("Pylint Test")
+ self.note = _("""This test uses Pylint and checks if the module satisfies the coding standard of Python. See http://www.logilab.org/project/name/pylint for further info.\n """)
self.bool_installed_only = False
self.ponderation = 1.0
+ self.result = ""
+ self.result_details = ""
return None
- def run_test(self, cr, uid, module_path, module_state):
+ def run_test(self, cr, uid, module_path):
config_file_path = config['addons_path']+'/base_module_quality/pylint_test/pylint_test_config.txt'
list_files = os.listdir(module_path)
for i in list_files:
@@ -52,12 +51,20 @@ class quality_test(base_module_quality.abstract_quality_check):
n = 0
score = 0.0
- detail = ""
- detail = "\n===Pylint Test===\n"
+ dict = {}
+ self.result_details += '''<html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="/tg_widgets/openerp/css/wiki.css" media="all">
+ </head>
+ <body>'''
for file in list_files:
if file.split('.')[-1] == 'py' and not file.endswith('__init__.py') and not file.endswith('__terp__.py'):
file_path = os.path.join(module_path, file)
- res = os.popen('pylint --rcfile=' + config_file_path + ' ' + file_path).read()
+ try:
+ res = os.popen('pylint --rcfile=' + config_file_path + ' ' + file_path).read()
+ except:
+ self.result += _("Error. Is pylint correctly installed?")+"\n"
+ break
n += 1
leftchar = -1
while res[leftchar:leftchar+1] != ' ' and leftchar-1 <= 0:
@@ -65,33 +72,26 @@ class quality_test(base_module_quality.abstract_quality_check):
rightchar = -10
while res[rightchar:rightchar+1] != '/' and rightchar+1 <= 0:
rightchar += 1
-
try:
score += float(res[leftchar+1:rightchar])
-# self.result += file + ": " + res[leftchar+1:rightchar] + "/10\n"
- detail += file + ": " + res[leftchar+1:rightchar] + "/10\n"
+ #self.result += file + ": " + res[leftchar+1:rightchar] + "/10\n"
+ dict[file] = [file, res[leftchar+1:rightchar]]
except:
score += 0
-# self.result += file + ": Unable to parse the result. Check the details.\n"
- detail += file + ": Unable to parse the result. Check the details.\n"
- self.result_details += res
- self.score = n and score / n or score
- if not self.bool_installed_only or module_state=="installed":
- summary ="""
-===Pylint Test===:
-
-This test checks if the module satisfies the current coding standard used by OpenERP.
-
-""" #+ "Score: " + str(self.score) + "/10\n"
- else:
- summary =""" \n===Pylint Test===:
-
-The module has to be installed before running this test.\n\n """
- header_list = ""
- self.error = True
- self.result = self.format_table(test='pylint', data_list=[summary,detail,self.error])
+ #self.result += file + ": "+_("Unable to parse the result. Check the details.")+"\n"
+ dict[file] = [file, _("Unable to parse the result. Check the details.")]
+ self.result_details += res.replace('''<div''', '''<div class="wikiwidget readonlyfield"''')
+ self.result_details += '</body></html>'
+ average_score = n and score / n or score
+ self.score = (max(average_score,0)) / 10
+ self.result = self.get_result(dict)
return None
+ def get_result(self, dict):
+ header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n', [_('File Name'), _('Result (/10)')])
+ if not self.error:
+ return self.format_table(header, data_list=dict)
+ return ""
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_module_quality/pylint_test/pylint_test_config.txt b/addons/base_module_quality/pylint_test/pylint_test_config.txt
index 2bb5bd12df0..eecbf011daf 100644
--- a/addons/base_module_quality/pylint_test/pylint_test_config.txt
+++ b/addons/base_module_quality/pylint_test/pylint_test_config.txt
@@ -62,7 +62,7 @@ disable-msg=C0103,F0401,E0611,R0903,W0232,W0102,E1002,R0913,R0904
# set the output format. Available formats are text, parseable, colorized and
# html
-output-format=text
+output-format=html
# Include message's id in output
include-ids=yes
diff --git a/addons/base_module_quality/speed_test/speed_test.py b/addons/base_module_quality/speed_test/speed_test.py
index d2ab88cbd14..33456e4729f 100644
--- a/addons/base_module_quality/speed_test/speed_test.py
+++ b/addons/base_module_quality/speed_test/speed_test.py
@@ -24,6 +24,7 @@ import netsvc
from osv import fields, osv
import os
from tools import config
+from tools.translate import _
import pooler
import time
@@ -35,83 +36,84 @@ class quality_test(base_module_quality.abstract_quality_check):
def __init__(self):
super(quality_test, self).__init__()
-# self.result = """
-#===Speed Test===:
-#
-#This test checks the speed of the module.
-#
-#"""
self.bool_installed_only = True
self.ponderation = 1.0
+ self.name = _("Speed Test")
+ self.note = _("""
+This test checks the speed of the module. Note that at least 5 demo data is needed in order to run it.
+
+""")
return None
- def run_test(self, cr, uid, module_path, module_state):
+
+ def run_test(self, cr, uid, module_path):
pool = pooler.get_pool(cr.dbname)
module_name = module_path.split('/')[-1]
-# self.result+=('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n! %-10s \n! %-10s \n! %-10s \n! %-20s') % ('Object Name'.ljust(40), 'Size-Number of Records (S)'.ljust(10), '1'.ljust(10), 'S/2'.ljust(10), 'S'.ljust(10), 'Complexity using query'.ljust(20))
- header_list = ['Object Name', 'Size-Number of Records (S)', '1', 'S/2', 'S', 'Complexity using query']
obj_list = self.get_objects(cr, uid, module_name)
obj_counter = 0
score = 0
obj_ids = self.get_ids(cr, uid, obj_list)
- detail = ""
- list1 = []
- for obj in obj_ids:
+ result_dict = {}
+ result_dict2 = {}
+ self.result_details += _("O(1) means that the number of SQL requests to read the object does not depand on the number of objects we are reading. This feature is hardly wished.\n")
+ for obj, ids in obj_ids.items():
obj_counter += 1
- ids = obj_ids[obj]
ids = ids[:100]
size = len(ids)
+ list2 = []
if size:
- c1 = cr.count
+ list = []
+ #we perform the operation twice, and count the number of queries in the second run. This allows to avoid the cache effect. (like translated terms that asks for more queries)
pool.get(obj).read(cr, uid, [ids[0]])
+ c = cr.count
pool.get(obj).read(cr, uid, [ids[0]])
- code_base_complexity = cr.count - c1
+ code_base_complexity = cr.count - c
pool.get(obj).read(cr, uid, ids[:size/2])
+ c = cr.count
pool.get(obj).read(cr, uid, ids[:size/2])
- code_half_complexity = cr.count - c1
+ code_half_complexity = cr.count - c
pool.get(obj).read(cr, uid, ids)
+ c = cr.count
pool.get(obj).read(cr, uid, ids)
- code_size_complexity = cr.count - c1
+ code_size_complexity = cr.count - c
if size < 5:
- self.score += -2
-# self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, code_base_complexity, code_half_complexity, code_size_complexity, "Warning! Not enough demo data")
- list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, "Warning! Not enough demo data"]
- list1.append(list)
+ list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, _("Warning! Not enough demo data")]
+ list2 = [obj, _("No enough data")]
else:
if code_size_complexity <= (code_base_complexity + size):
- complexity = "O(1)"
- score = 10
+ complexity = _("O(1)")
+ score += 1
+ list2 = [obj, _("Efficient")]
else:
- complexity = "O(n) or worst"
- score = 0
-# self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, code_base_complexity, code_half_complexity, code_size_complexity, complexity)
+ complexity = _("O(n) or worst")
+ list2 = [obj, _("Not Efficient")]
+
list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, complexity]
- list1.append(list)
+
else:
- score += -5
-# self.result += ('\n|-\n| %s \n| %s \n| %s \n| %s \n| %s \n| %s ') % (obj, size, "", "", "", "Warning! Object has no demo data")
- list = [obj, size, "", "", "", "Warning! Object has no demo data"]
- list1.append(list)
-# self.result += '\n|}\n'
- self.score = obj_counter and score/obj_counter or 0.0
- if not self.bool_installed_only or module_state=="installed":
- summary = """
-===Speed Test===:
-
-This test checks the speed of the module.
-
-"""#+ "Score: " + str(self.score) + "/10\n"
- else:
- summary =""" \n===Speed Test===:
-
-The module has to be installed before running this test.\n\n """
- header_list = ""
- self.error = True
- self.result = self.format_table(test='speed', header=header_list, data_list=[summary,list1,self.error])
+ list = [obj, size, "", "", "", _("Warning! Object has no demo data")]
+ list2 = [obj, _("No data")]
+ result_dict[obj] = list
+ result_dict2[obj] = list2
+ self.score = obj_counter and score / obj_counter or 0.0
+ self.result_details += self.get_result_details(result_dict)
+ self.result += self.get_result(result_dict2)
return None
+ def get_result(self, dict):
+ header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s', [_('Object Name'), _('Result')])
+ if not self.error:
+ return self.format_table(header, data_list=dict)
+ return ""
+
+ def get_result_details(self, dict):
+ header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n! %-10s \n! %-10s \n! %-10s \n! %-20s', [_('Object Name'), _('N (Number of Records)'), _('1'), _('N/2'), _('N'), _('Reading Complexity')])
+ if not self.error:
+ return self.format_table(header, data_list=dict)
+ return ""
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_module_quality/terp_test/terp_test.py b/addons/base_module_quality/terp_test/terp_test.py
index e3bbaa356ea..cf9977c89b7 100644
--- a/addons/base_module_quality/terp_test/terp_test.py
+++ b/addons/base_module_quality/terp_test/terp_test.py
@@ -30,16 +30,23 @@ import re
class quality_test(base_module_quality.abstract_quality_check):
def __init__(self):
- '''
- This test checks the quality of __terp__.py file in the selected module.
- '''
+# '''
+# This test checks the quality of __terp__.py file in the selected module.
+# '''
super(quality_test, self).__init__()
- self.bool_installed_only = True
+ self.name = _("Terp Test")
+ self.note = _("This test checks if the module satisfies the current coding standard used by OpenERP.")
+ self.bool_installed_only = False
+ self.no_terp = False
+ self.ponderation = 2
+
return None
- def run_test(self, cr, uid, module_path, module_state):
- no_terp = False
+ def run_test_terp(self, cr, uid, module_path):
list_files = os.listdir(module_path)
+
+ current_module = module_path.split('/')[-1]
+
for i in list_files:
path = os.path.join(module_path, i)
if os.path.isdir(path):
@@ -50,59 +57,84 @@ class quality_test(base_module_quality.abstract_quality_check):
score = 0.0
feel_good_factor = 0
feel_bad_factor = 0
- detail = "\n===TERP Test===\n"
- summary = "\n===TERP Test===:\n"
-
if '__terp__.py' not in list_files:
- no_terp = True
-
- if no_terp:
- summary += """
-The module does not contain the __terp__.py file.\n\n """
- header_list = ""
- self.error = True
- self.result = self.format_table(test='terp', data_list=[summary, detail, self.error])
+ self.no_terp = True
+ self.result += _("The module does not contain the __terp__.py file")
return None
terp_file = os.path.join(module_path,'__terp__.py')
res = eval(tools.file_open(terp_file).read())
- terp_keys = ['category', 'name', 'description', 'author', 'website', 'update_xml', 'init_xml', 'depends', 'version', 'active', 'installable', 'demo_xml']
+ terp_keys = ['category', 'name', 'description', 'author', 'website', 'update_xml', 'init_xml', 'depends', 'version', 'active', 'installable', 'demo_xml', 'certificate']
for key in terp_keys:
if key in res:
- feel_good_factor += 1
+ feel_good_factor += 1 # each tag should appear
if isinstance(res[key],(str,unicode)):
if not res[key]:
feel_bad_factor += 1
else:
- if key == 'description' and res[key] and len(str(res[key]))>=25:
+
+ if key == 'description' and res[key] and len(str(res[key])) >= 150: # no. of chars should be >=150
feel_good_factor += 1
if res['description'].count('\n') >= 4:# description contains minimum 5 lines
feel_good_factor += 1
if key == 'website':
- ptrn = re.compile('https?://[\w\.]*') # reg ex matching on temporary basis.
+ ptrn = re.compile('https?://[\w\.]*') # reg ex matching on temporary basis.Website is correctly formatted
result = ptrn.search(str(res[key]))
if result:
feel_good_factor += 1
+ else:
+ feel_bad_factor += 1
+
+ if isinstance(res[key],bool):
+ if key == 'active':
+ if current_module != 'base':
+ if res[key]:
+ feel_bad_factor += 1
+ else:
+ if not res[key]:
+ feel_bad_factor += 1
+
+ if key == 'installable' and not res[key]: # installable tag is provided and True
+ feel_bad_factor +=1
else:
feel_bad_factor += 1
- self.score = round((feel_good_factor * 10) / float(feel_good_factor + feel_bad_factor),2)
-# if not self.bool_installed_only or module_state=="installed":
- summary += """
-This test checks if the module satisfies the current coding standard for __terp__.py file used by OpenERP.
+ score = round((feel_good_factor) / float(feel_good_factor + feel_bad_factor),2)
-"""
-# else:
-# summary += """
-#The module has to be installed before running this test.\n\n """
-# header_list = ""
-# error = True
+# self.result += "__terp__.py : "+ str(self.score) + "/10\n"
+ return [_('__terp__.py file'), score]
- detail += "__terp__.py : "+ str(self.score) + "/10\n"
- self.result = self.format_table(test='terp', data_list=[summary, detail, self.error])
+
+ def run_test(self, cr, uid, module_path):
+ terp_score = self.run_test_terp(cr, uid, module_path)
+ self.score = terp_score[1]
+ self.result = self.get_result({'__terp__.py': terp_score})
return None
+ def get_result(self, dict):
+ header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n', [_('Object Name'), _('Result (/1)'),])
+ if not self.error:
+ return self.format_table(header, data_list=dict)
+ return ""
+
+ #~ def get_result(self, cr, uid, module_path, module_state):
+#~ # self.run_test(cr, uid, module_path)
+#~ # summary = "\n===TERP Test===:\n"
+ #~ if self.no_terp:
+ #~ summary += """
+#~ The module does not contain the __terp__.py file.\n\n """
+#~ # else:
+#~ # summary += """
+#~ # This test checks if the module satisfies the current coding standard for __terp__.py file used by OpenERP.
+#~ # """ + "Score: " + str(self.score) + "/10\n"
+ #~ return summary
+
+ #~ def get_result_details(self):
+ #~ detail = "\n===TERP Test===\n" + self.result
+ #~ return detail
+
+
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_module_quality/wizard/module_quality_check.py b/addons/base_module_quality/wizard/module_quality_check.py
index 1da35f9f68a..002810b7976 100644
--- a/addons/base_module_quality/wizard/module_quality_check.py
+++ b/addons/base_module_quality/wizard/module_quality_check.py
@@ -27,108 +27,108 @@ import tools
import os
from base_module_quality import base_module_quality
-#TODO: (utiliser les nouveaux wizards pour heriter la vue et rajouter un onglet par test?)
-#TODO: implement the speed test
-#TODO: add cheks: do the class quality_check inherits the class abstract_quality_check?
-#TODO: improve translability
-#TODO: clean
-
-
-#To keep or not? to be discussed...
-
-#~ view_form = """<?xml version="1.0"?>
-#~ <form string="Check quality">
- #~ <notebook>
- #~ <page string="Summary">
- #~ <field name="general_info" widget="text_wiki" nolabel="1" colspan="4" height="350" width="800"/>
- #~ </page>
- #~ </notebook>
-#~ </form>"""
-
-
-#~ view_field = {
- #~ "general_info": {'type': 'text', 'string': 'General Info', 'readonly':True},
-#~ }
+#TODO: add cheks: do the class quality_check inherits the class abstract_quality_check?
-class wiz_quality_check(osv.osv_memory):
-# general_info = ""
+class wiz_quality_check(osv.osv):
_name = 'wizard.quality.check'
-
- def _check(self, cr, uid, data, context={}):
- string_ret = ""
- string_detail = ""
- from tools import config
- data['ids'] = data.get('module_id', False)
- pool = pooler.get_pool(cr.dbname)
- module_data = pool.get('ir.module.module').browse(cr, uid, [data['ids']])
- list_folders = os.listdir(config['addons_path']+'/base_module_quality/')
- module_name = module_data[0].name
- abstract_obj = base_module_quality.abstract_quality_check()
- score_sum = 0.0
- ponderation_sum = 0.0
- final_score = ""
- for test in abstract_obj.tests:
- ad = tools.config['addons_path']
- if module_data[0].name == 'base':
- ad = tools.config['root_path']+'/addons'
- module_path = os.path.join(ad, module_data[0].name)
- val = test.quality_test()
- val.run_test(cr, uid, str(module_path), str(module_data[0].state))
- string_ret += val.result['summary'] #summary tab
- if not val.error:
- string_ret += "Score: " + str(val.score) + "/10\n" #val.score = val.score * val.ponderation ???
- string_detail += val.result['detail'] # detail tab
- score_sum += (val.add_quatation(val.score, 10) * val.ponderation)
- ponderation_sum += val.ponderation
- final_score = str(score_sum / ponderation_sum * 100) + "%"
- string_ret += "\n\nPonderation Result for module:" + final_score
- self.string_detail = string_detail
- return ""
-
- def _check_detail(self, cr, uid, data, context={}):
- return self.string_detail
-
-
-# def _general_info(self, cr, uid, data, context={}):
-# return self.general_info
-
- #~ states = {
-
- #~ 'init': {
- #~ 'actions': [_check],
- #~ 'result': {'type':'form', 'arch':view_form, 'fields':view_field, 'state':[('end','Ok')]},
- #~ },
- #~ }
-#To keep or not? to be discussed...
-
- #~ 'init': {
- #~ 'actions': [],
- #~ 'result': {'type':'form', 'arch':form_check, 'fields':fields_check, 'state':[('end','Cancel'),('do','Do Test')]}
- #~ },
_columns = {
-# 'general_info': fields.text('General Info', readonly="1",),
-# 'detail' : fields.text('Detail', readonly="0",),
- 'verbose_detail' : fields.one2many('quality.check.detail', 'quality_check', 'Verbose Detail', readonly="0",)
+ 'name': fields.char('Rated Module', size=64, ),
+ 'final_score': fields.char('Final Score (%)', size=10,),
+ 'test_ids' : fields.one2many('quality.check.detail', 'quality_check_id', 'Tests',)
}
- _defaults = {
-# 'general_info': _check,
-# 'detail': _check_detail
- 'verbose_detail': _check,
- }
-
wiz_quality_check()
-class quality_check_detail(osv.osv_memory):
+
+class quality_check_detail(osv.osv):
_name = 'quality.check.detail'
- _rec_name = 'quality_check'
_columns = {
- 'quality_check': fields.many2one('wizard.quality.check', 'Quality'),
- 'general_info': fields.text('General Info', readonly="1",),
- 'detail' : fields.text('Detail', readonly="1",),
+ 'quality_check_id': fields.many2one('wizard.quality.check', 'Quality'),
+ 'name': fields.char('Name',size=128,),
+ 'score': fields.float('Score (%)',),
+ 'ponderation': fields.float('Ponderation',help='Some tests are more critical than others, so they have a bigger weight in the computation of final rating'),
+ 'note': fields.text('Note',),
+ 'summary': fields.text('Summary',),
+ 'detail' : fields.text('Details',),
+ 'state': fields.selection([('done','Done'),('skipped','Skipped'),], 'State', size=6, help='The test will be completed only if the module is installed or if the test may be processed on uninstalled module.'),
}
quality_check_detail()
+
+class create_quality_check(wizard.interface):
+
+ def _create_quality_check(self, cr, uid, data, context={}):
+ pool = pooler.get_pool(cr.dbname)
+ print data, context
+ objs = []
+ for id in data['ids']:
+ module_data = pool.get('ir.module.module').browse(cr, uid, id)
+ #list_folders = os.listdir(config['addons_path']+'/base_module_quality/')
+ abstract_obj = base_module_quality.abstract_quality_check()
+ score_sum = 0.0
+ ponderation_sum = 0.0
+ create_ids = []
+ for test in abstract_obj.tests:
+ ad = tools.config['addons_path']
+ if module_data.name == 'base':
+ ad = tools.config['root_path']+'/addons'
+ module_path = os.path.join(ad, module_data.name)
+ val = test.quality_test()
+
+ if not val.bool_installed_only or module_data.state=="installed":
+ val.run_test(cr, uid, str(module_path))
+ data = {
+ 'name': val.name,
+ 'score': val.score * 100,
+ 'ponderation': val.ponderation,
+ 'summary': val.result,
+ 'detail': val.result_details,
+ 'state': 'done',
+ 'note': val.note,
+ }
+ create_ids.append((0,0,data))
+ score_sum += val.score * val.ponderation
+ ponderation_sum += val.ponderation
+ else:
+ data = {
+ 'name': val.name,
+ 'note': val.note,
+ 'score': 0,
+ 'state': 'skipped',
+ 'summary': _("The module has to be installed before running this test.")
+ }
+ create_ids.append((0,0,data))
+
+ final_score = str(score_sum / ponderation_sum * 100) + "%"
+ data = {
+ 'name': module_data.name,
+ 'final_score': final_score,
+ 'test_ids' : create_ids,
+ }
+ obj = pool.get('wizard.quality.check').create(cr, uid, data, context)
+ objs.append(obj)
+ return objs
+
+ def _open_quality_check(self, cr, uid, data, context):
+ obj_ids = self._create_quality_check(cr, uid, data, context)
+ return {
+ 'domain': "[('id','in', ["+','.join(map(str,obj_ids))+"])]",
+ 'name': _('Quality Check'),
+ 'view_type': 'form',
+ 'view_mode': 'tree,form',
+ 'res_model': 'wizard.quality.check',
+ 'type': 'ir.actions.act_window'
+ }
+
+ states = {
+ 'init' : {
+ 'actions' : [],
+ 'result': {'type':'action', 'action':_open_quality_check, 'state':'end'}
+ }
+ }
+
+create_quality_check("create_quality_check_wiz")
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: