base_module_quality improvements:

*added note field 
*improved transability
*improved output
*cleaned
*modified format_table method

bzr revid: qdp@tinyerp.com-20090108130320-ypcc4jxbx51jv1ra
This commit is contained in:
qdp
2009-01-08 14:03:20 +01:00
parent b141de765d
commit 8a06bea953
7 changed files with 78 additions and 56 deletions
@@ -41,6 +41,9 @@ class abstract_quality_check(object):
#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 = ""
@@ -38,6 +38,7 @@
<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"/>
@@ -32,6 +32,9 @@ class quality_test(base_module_quality.abstract_quality_check):
def __init__(self):
super(quality_test, self).__init__()
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
@@ -47,38 +50,32 @@ class quality_test(base_module_quality.abstract_quality_check):
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_dict[obj] = temp
self.score = (ok_count + ex_count) and float(ok_count)/float(ok_count + ex_count) or 0.0
self.result = self.get_result()
self.result_details = self.get_result_details(result_dict)
self.result = self.get_result(result_dict)
return None
def get_result(self):
summary = """
This test checks if the module classes are raising exception when calling basic methods or not.
"""
return summary
def get_result_details(self, dict):
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:
@@ -32,6 +32,7 @@ class quality_test(base_module_quality.abstract_quality_check):
def __init__(self):
super(quality_test, self).__init__()
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
return None
@@ -47,8 +48,8 @@ class quality_test(base_module_quality.abstract_quality_check):
n = 0
score = 0.0
self.result += """\nThis test checks if the module satisfies the current coding standard used by OpenERP. \n
Rating for *.py files goes from -10/10 to 10/10\n\n"""
dict = {}
self.result_details += '<nowiki>'
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)
@@ -66,36 +67,24 @@ Rating for *.py files goes from -10/10 to 10/10\n\n"""
rightchar += 1
try:
score += float(res[leftchar+1:rightchar])
self.result += 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"
#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
self.result_details += '</nowiki>'
average_score = n and score / n or score
self.score = (average_score + 10) / 20
self.score = (max(average_score,0)) / 10
self.result = self.get_result(dict)
return None
#~ def get_result(self, cr, uid, module_path):
#~ self.run_test(cr, uid, module_path)
#~ 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
#~ return summary
#~ def get_result_details(self):
#~ detail = "\n===Pylint Test===\n" + self.result
#~ return detail
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:
@@ -35,9 +35,13 @@ class quality_test(base_module_quality.abstract_quality_check):
def __init__(self):
super(quality_test, self).__init__()
self.name = _("Speed Test")
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):
@@ -48,6 +52,8 @@ class quality_test(base_module_quality.abstract_quality_check):
score = 0
obj_ids = self.get_ids(cr, uid, obj_list)
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 in obj_ids:
obj_counter += 1
ids = obj_ids[obj]
@@ -73,29 +79,38 @@ class quality_test(base_module_quality.abstract_quality_check):
code_size_complexity = cr.count - c
if size < 5:
list = [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")]
else:
if code_size_complexity <= (code_base_complexity + size):
complexity = "O(1)"
complexity = _("O(1)")
score += 1
list2 = [obj, _("Efficient")]
else:
complexity = "O(n) or worst"
complexity = _("O(n) or worst")
list2 = [obj, _("Not Efficient")]
list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, complexity]
else:
list = [obj, size, "", "", "", "Warning! Object has no demo data"]
list = [obj, size, "", "", "", _("Warning! Object has no demo data")]
list2 = [obj, _("No demo 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_details += self.get_result_details(result_dict)
self.result += self.get_result(result_dict2)
return None
def get_result(self):
summary = """
This test checks the speed of the module.
"""
return summary
def get_result(self, dict):
header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n', [_('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'), _('Size-Number of Records (S)'), _('1'), _('S/2'), _('S'), _('Reading Complexity')])
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 ""
@@ -35,13 +35,14 @@ class quality_test(base_module_quality.abstract_quality_check):
# '''
super(quality_test, self).__init__()
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):
def run_test_terp(self, cr, uid, module_path):
list_files = os.listdir(module_path)
current_module = module_path.split('/')[-1]
@@ -58,7 +59,7 @@ class quality_test(base_module_quality.abstract_quality_check):
feel_bad_factor = 0
if '__terp__.py' not in list_files:
self.no_terp = True
self.result += "The module does not contain the __terp__.py file"
self.result += _("The module does not contain the __terp__.py file")
return None
terp_file = os.path.join(module_path,'__terp__.py')
@@ -100,11 +101,24 @@ class quality_test(base_module_quality.abstract_quality_check):
else:
feel_bad_factor += 1
self.score = round((feel_good_factor) / float(feel_good_factor + feel_bad_factor),2)
self.result += "\nThis 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)
# self.result += "__terp__.py : "+ str(self.score) + "/10\n"
return [_('__terp__.py file'), score]
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"
@@ -48,6 +48,7 @@ class quality_check_detail(osv.osv):
'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.'),
@@ -84,6 +85,7 @@ class create_quality_check(wizard.interface):
'summary': val.result,
'detail': val.result_details,
'state': 'done',
'note': val.note,
}
create_ids.append((0,0,data))
score_sum += val.score * val.ponderation
@@ -91,6 +93,7 @@ class create_quality_check(wizard.interface):
else:
data = {
'name': val.name,
'note': val.note,
'score': 0,
'state': 'skipped',
'summary': _("The module has to be installed before running this test.")