def testCoverage(self): print('CTEST_FULL_OUTPUT') prefixPath = os.environ['QGIS_PREFIX_PATH'] docPath = os.path.join(prefixPath, '..', 'doc', 'api', 'xml') parser = DoxygenParser(docPath, ACCEPTABLE_MISSING_DOCS, ACCEPTABLE_MISSING_ADDED_NOTE, ACCEPTABLE_MISSING_BRIEF) coverage = 100.0 * parser.documented_members / parser.documentable_members missing = parser.documentable_members - parser.documented_members print("---------------------------------") printImportant("{} total documentable members".format(parser.documentable_members)) printImportant("{} total contain valid documentation".format(parser.documented_members)) printImportant("Total documentation coverage {}%".format(coverage)) printImportant("---------------------------------") printImportant("{} members missing documentation".format(missing)) print("---------------------------------") print("Unacceptable missing documentation:") print(parser.undocumented_string) assert len(parser.undocumented_string) == 0, 'FAIL: new undocumented members have been introduced, please add documentation for these members' self.assertTrue(len(parser.classes_missing_group) == 0, 'FAIL: {} classes have been added without Doxygen group tags ("\ingroup"):\n{}'.format(len(parser.classes_missing_group), '\n'.join(parser.classes_missing_group))) self.assertTrue(len(parser.classes_missing_version_added) == 0, 'FAIL: {} classes have been added without a version added doxygen note ("@note added in QGIS x.xx"):\n{}'.format(len(parser.classes_missing_version_added), '\n'.join(parser.classes_missing_version_added))) self.assertTrue(len(parser.classes_missing_brief) == 0, 'FAIL: {} classes have been added without a brief description:\n{}'.format(len(parser.classes_missing_brief), '\n'.join(parser.classes_missing_brief)))
def testCoverage(self): print('CTEST_FULL_OUTPUT') prefixPath = os.environ['QGIS_PREFIX_PATH'] docPath = os.path.join(prefixPath, '..', 'doc', 'api', 'xml') parser = DoxygenParser(docPath, ACCEPTABLE_MISSING_DOCS, ACCEPTABLE_MISSING_ADDED_NOTE, ACCEPTABLE_MISSING_BRIEF) coverage = 100.0 * parser.documented_members / parser.documentable_members missing = parser.documentable_members - parser.documented_members print("---------------------------------") print(("{} total documentable members".format(parser.documentable_members))) print(("{} total contain valid documentation".format(parser.documented_members))) print(("Total documentation coverage {}%".format(coverage))) print("---------------------------------") print(("{} members missing documentation".format(missing))) print("---------------------------------") print("Unacceptable missing documentation:") if parser.undocumented_members: for cls, props in list(parser.undocumented_members.items()): print(('\n\nClass {}, {}/{} members documented\n'.format(colored(cls, 'yellow'), props['documented'], props['members']))) for mem in props['missing_members']: print((colored(' ' + mem, 'yellow', attrs=['bold']))) # self.assertEquals(len(parser.undocumented_string), 0, 'FAIL: new undocumented members have been introduced, please add documentation for these members') if parser.classes_missing_group: print("---------------------------------") print('\n') print((colored('{} classes have been added without Doxygen group tag ("\ingroup"):'.format(len(parser.classes_missing_group)), 'yellow'))) print('') print((' ' + '\n '.join([colored(cls, 'yellow', attrs=['bold']) for cls in parser.classes_missing_group]))) if parser.classes_missing_version_added: print("---------------------------------") print('\n') print((colored('{} classes have been added without a version added doxygen note ("@note added in QGIS x.xx"):'.format(len(parser.classes_missing_version_added)), 'yellow'))) print('') print((' ' + '\n '.join([colored(cls, 'yellow', attrs=['bold']) for cls in parser.classes_missing_version_added]))) if parser.classes_missing_brief: print("---------------------------------") print('\n') print((colored('{} classes have been added without at least a brief description:'.format(len(parser.classes_missing_brief)), 'yellow'))) print('') print((' ' + '\n '.join([colored(cls, 'yellow', attrs=['bold']) for cls in parser.classes_missing_brief]))) sys.stdout.flush() self.assertTrue(not parser.undocumented_members, 'Undocumented members found') self.assertTrue(not parser.classes_missing_group, 'Classes without \group tag found') self.assertTrue(not parser.classes_missing_version_added, 'Classes without version added note found') self.assertTrue(not parser.classes_missing_brief, 'Classes without brief description found')
def testCoverage(self): print 'CTEST_FULL_OUTPUT' prefixPath = os.environ['QGIS_PREFIX_PATH'] docPath = os.path.join(prefixPath, '..', 'doc', 'api', 'xml') parser = DoxygenParser(docPath) coverage = 100.0 * parser.documented_members / parser.documentable_members missing = parser.documentable_members - parser.documented_members print "---------------------------------" printImportant("{} total documentable members".format(parser.documentable_members)) printImportant("{} total contain valid documentation".format(parser.documented_members)) printImportant("Total documentation coverage {}%".format(coverage)) printImportant("---------------------------------") printImportant("{} members missing documentation, out of {} allowed".format(missing, ACCEPTABLE_MISSING_DOCS)) print "---------------------------------" print parser.undocumented_string assert missing <= ACCEPTABLE_MISSING_DOCS, 'FAIL: new undocumented members have been introduced, please add documentation for these members'
def testCoverage(self): print('CTEST_FULL_OUTPUT') prefixPath = os.environ['QGIS_PREFIX_PATH'] docPath = os.path.join(prefixPath, '..', 'doc', 'api', 'xml') parser = DoxygenParser(docPath) # first look for objects without any bindings objects = set([m[0] for m in parser.bindable_members]) missing_objects = [] bound_objects = {} for o in objects: try: if '::' in o: bound_objects[o] = getattr(globals()[o.split('::')[0]], o.split('::')[1]) else: bound_objects[o] = globals()[o] except: missing_objects.append(o) missing_objects.sort() # next check for individual members parser.bindable_members.sort() missing_members = [] for m in parser.bindable_members: if m[0] in bound_objects: obj = bound_objects[m[0]] if "::" in m[0] and m[0].split("::")[1] == m[1]: # skip constructors of nested classes continue # try two different methods of checking for member existence try: if hasattr(obj, m[1]): continue except: pass try: if m[1] in dir(obj): continue except: printImportant( "SIP coverage test: something strange happened in {}.{}, obj={}" .format(m[0], m[1], obj)) missing_members.append('{}.{}'.format(m[0], m[1])) missing_members.sort() if missing_objects: print("---------------------------------") print((colored('Missing classes:', 'yellow'))) print((' ' + '\n '.join([ colored(obj, 'yellow', attrs=['bold']) for obj in missing_objects ]))) if missing_members: print("---------------------------------") print((colored('Missing members:', 'yellow'))) print((' ' + '\n '.join([ colored(mem, 'yellow', attrs=['bold']) for mem in missing_members ]))) # print summaries missing_class_count = len(missing_objects) present_count = len(objects) - missing_class_count coverage = 100.0 * present_count / len(objects) print("---------------------------------") printImportant("{} total bindable classes".format(len(objects))) printImportant("{} total have bindings".format(present_count)) printImportant("Binding coverage by classes {}%".format(coverage)) printImportant("---------------------------------") printImportant( "{} classes missing bindings".format(missing_class_count)) print("---------------------------------") missing_member_count = len(missing_members) present_count = len(parser.bindable_members) - missing_member_count coverage = 100.0 * present_count / len(parser.bindable_members) print("---------------------------------") printImportant("{} total bindable members".format( len(parser.bindable_members))) printImportant("{} total have bindings".format(present_count)) printImportant("Binding coverage by members {}%".format(coverage)) printImportant("---------------------------------") printImportant( "{} members missing bindings".format(missing_member_count)) self.assertEqual( missing_class_count, 0, """\n\nFAIL: new unbound classes have been introduced, please add SIP bindings for these classes If these classes are not suitable for the Python bindings, please add the Doxygen tag "@note not available in Python bindings" to the CLASS Doxygen comments""") self.assertEqual( missing_member_count, 0, """\n\nFAIL: new unbound members have been introduced, please add SIP bindings for these members If these members are not suitable for the Python bindings, please add the Doxygen tag "@note not available in Python bindings" to the MEMBER Doxygen comments""")
def testCoverage(self): print 'CTEST_FULL_OUTPUT' prefixPath = os.environ['QGIS_PREFIX_PATH'] docPath = os.path.join(prefixPath, '..', 'doc', 'api', 'xml') parser = DoxygenParser(docPath) #first look for objects without any bindings objects = set([m[0] for m in parser.bindable_members]) missing_objects = [] bound_objects = {} for o in objects: try: bound_objects[o] = globals()[o] except: missing_objects.append(o) missing_objects.sort() missing_count = len(missing_objects) present_count = len(objects) - missing_count coverage = 100.0 * present_count / len(objects) print "---------------------------------" printImportant("{} total bindable classes".format(len(objects))) printImportant("{} total have bindings".format(present_count)) printImportant("Binding coverage by classes {}%".format(coverage)) printImportant("---------------------------------") printImportant("{} classes missing bindings, out of {} allowed".format( missing_count, ACCEPTABLE_MISSING_CLASSES)) print "---------------------------------" assert missing_count <= ACCEPTABLE_MISSING_CLASSES, """\n\nFAIL: new unbound classes have been introduced, please add SIP bindings for these classes If these classes are not suitable for the Python bindings, please add the Doxygen tag "@note not available in Python bindings" to the CLASS Doxygen comments""" #next check for individual members parser.bindable_members.sort() missing_members = [] for m in parser.bindable_members: if m[0] in bound_objects: obj = bound_objects[m[0]] if not hasattr(obj, m[1]): missing_members.append('{}.{}'.format(m[0], m[1])) missing_members.sort() missing_count = len(missing_members) present_count = len(parser.bindable_members) - missing_count coverage = 100.0 * present_count / len(parser.bindable_members) print "---------------------------------" printImportant("{} total bindable members".format( len(parser.bindable_members))) printImportant("{} total have bindings".format(present_count)) printImportant("Binding coverage by members {}%".format(coverage)) printImportant("---------------------------------") printImportant("{} members missing bindings, out of {} allowed".format( missing_count, ACCEPTABLE_MISSING_MEMBERS)) print "---------------------------------" print 'Missing classes:\n {}'.format('\n '.join(missing_objects)) print "---------------------------------" print 'Missing members:\n {}'.format('\n '.join(missing_members)) assert missing_count <= ACCEPTABLE_MISSING_MEMBERS, """\n\nFAIL: new unbound members have been introduced, please add SIP bindings for these members