def test_option_values(HANDLER, PROJECT): """test for ancestor, associated and module options""" df_h = DiaDefGenerator(Linker(PROJECT), HANDLER) cl_config = Config() cl_config.classes = ["Specialization"] cl_h = DiaDefGenerator(Linker(PROJECT), DiadefsHandler(cl_config)) assert df_h._get_levels() == (0, 0) assert not df_h.module_names assert cl_h._get_levels() == (-1, -1) assert cl_h.module_names for hndl in [df_h, cl_h]: hndl.config.all_ancestors = True hndl.config.all_associated = True hndl.config.module_names = True hndl._set_default_options() assert hndl._get_levels() == (-1, -1) assert hndl.module_names handler = DiadefsHandler(Config()) df_h = DiaDefGenerator(Linker(PROJECT), handler) cl_config = Config() cl_config.classes = ["Specialization"] cl_h = DiaDefGenerator(Linker(PROJECT), DiadefsHandler(cl_config)) for hndl in [df_h, cl_h]: hndl.config.show_ancestors = 2 hndl.config.show_associated = 1 hndl.config.module_names = False hndl._set_default_options() assert hndl._get_levels() == (2, 1) assert not hndl.module_names
def test_option_values(default_config: PyreverseConfig, HANDLER: DiadefsHandler, PROJECT: Project) -> None: """Test for ancestor, associated and module options.""" df_h = DiaDefGenerator(Linker(PROJECT), HANDLER) cl_config = default_config cl_config.classes = ["Specialization"] cl_h = DiaDefGenerator(Linker(PROJECT), DiadefsHandler(cl_config)) assert df_h._get_levels() == (0, 0) assert not df_h.module_names assert cl_h._get_levels() == (-1, -1) assert cl_h.module_names for hndl in (df_h, cl_h): hndl.config.all_ancestors = True hndl.config.all_associated = True hndl.config.module_names = True hndl._set_default_options() assert hndl._get_levels() == (-1, -1) assert hndl.module_names handler = DiadefsHandler(default_config) df_h = DiaDefGenerator(Linker(PROJECT), handler) cl_config = default_config cl_config.classes = ["Specialization"] cl_h = DiaDefGenerator(Linker(PROJECT), DiadefsHandler(cl_config)) for hndl in (df_h, cl_h): hndl.config.show_ancestors = 2 hndl.config.show_associated = 1 hndl.config.module_names = False hndl._set_default_options() assert hndl._get_levels() == (2, 1) assert not hndl.module_names
def run(self, args): """checking arguments and run project""" if not args: print(self.help()) return 1 # insert current working directory to the python path to recognize # dependencies to local modules even if cwd is not in the PYTHONPATH sys.path.insert(0, os.getcwd()) try: project = self.manager.project_from_files(args) linker = Linker(project, tag=True) handler = DiadefsHandler(self.config) diadefs = handler.get_diadefs(project, linker) finally: sys.path.pop(0) # For some reason the diagram titles are #not set correctly, so fix that here if needed. title = args[-1] for diagram in diadefs: if "No Name" in diagram.title: diagram.title = title try: packageDiagram, classDiagram = diadefs writePackageDiagram(packageDiagram) except ValueError: classDiagram = diadefs[0] writeClassDiagram(classDiagram)
def run(self, args): """checking arguments and run project""" if not args: print(self.help()) return 1 # insert current working directory to the python path to recognize # dependencies to local modules even if cwd is not in the PYTHONPATH sys.path.insert(0, os.getcwd()) try: project = project_from_files( args, project_name=self.config.project, black_list=self.config.black_list, ) linker = Linker(project, tag=True) handler = DiadefsHandler(self.config) diadefs = handler.get_diadefs(project, linker) finally: sys.path.pop(0) if self.config.output_format == "vcg": writer.VCGWriter(self.config).write(diadefs) else: writer.DotWriter(self.config).write(diadefs) return 0
def run(self, args): """checking arguments and run project""" if not args: print self.help() return # insert current working directory to the python path to recognize # dependencies to local modules even if cwd is not in the PYTHONPATH sys.path.insert(0, args[0]) sys.path.insert(0, os.getcwd()) try: project = self.manager.project_from_files(args, black_list= \ map(os.path.relpath, BlackList.blacklist)) linker = Linker(project, tag=True) handler = DiadefsHandler(self.config) diadefs = handler.get_diadefs(project, linker) finally: sys.path.pop(0) # filter just classes (not packages) for now diadefs = filter(lambda x: x.TYPE == 'class', diadefs) # update GUI Gdk.threads_enter() self.callback() writer.CanvasWriter(self.view, self.config).write(diadefs) Gdk.threads_leave()
def test_functional_relation_extraction(self): """functional test of relations extraction; different classes possibly in different modules""" # XXX should be catching pyreverse environnement problem but doesn't # pyreverse doesn't extracts the relations but this test ok project = get_project("data") handler = DiadefsHandler(Config()) diadefs = handler.get_diadefs(project, Linker(project, tag=True)) cd = diadefs[1] relations = _process_relations(cd.relationships) assert relations == self._should_rels
def run(self, args): """checking arguments and run project""" if not args: print self.help() return project = self.manager.project_from_files(args, astng_wrapper) linker = Linker(project, tag=True) handler = DiadefsHandler(self.config) diadefs = handler.get_diadefs(project, linker) if self.config.output_format == "vcg": writer.VCGWriter(self.config).write(diadefs) else: writer.DotWriter(self.config).write(diadefs)
def run(self, args): """checking argmuents and run project""" if not args: print self.help() return project = self.manager.project_from_files(args, astng_wrapper) linker = Linker(project, tag=True) handler = DiadefsHandler(self.config) diadefs = handler.get_diadefs(project, linker) if self.config.output_format == "vcg": writer.VCGWriter(self.config).write(diadefs) else: writer.DotWriter(self.config).write(diadefs)
def run(self, args): project = self.manager.project_from_files(args) linker = Linker(project, tag=True) handler = DiadefsHandler(self.config) diadefs = handler.get_diadefs(project, linker) root = etree.Element("Classes") classes = None for diagram in diadefs: if diagram.TYPE == 'class': classes = diagram class_map = {} class_nodes = [] for c in classes.objects: ''' First pass - id generation ''' c_id = str(self.generate_id()) node = etree.Element("Class",name=c.title,id=c_id,label=c.node.root().name) if class_map.has_key(c.title): print "Duplicate class name - ",c.title else: class_map[c.title] = c_id root.append(node) class_nodes.append((c,node)) attr_num = 0 typed_attrs = 0 for c, node in class_nodes: ''' Second pass - linking ''' attr_num += len(c.attrs) for a in c.attrs: a_data = [w.strip() for w in a.split(':')] found_attr = False attr_node = etree.Element('Attr',name=a_data[0]) if (len(a_data) > 1): types = [w.strip() for w in a_data[1].split(',')] for t in types: if class_map.has_key(t): print "InnerType!" found_attr = True type_node = etree.Element('CommonType', id=class_map[a_data[1]],name=a_data[1]) attr_node.append(type_node) if found_attr: typed_attrs += 1 node.append(attr_node) #mapper[obj] = node print "Numbers of all attributes in project: ", attr_num print "Numbers of typed attributes in project: ", typed_attrs print "Percentage: ", typed_attrs*1.0/attr_num print "Writing ", self._out_file f = open(self._out_file,'w') f.write(etree.tostring(root, pretty_print=True, encoding='utf-8', xml_declaration=True)) f.close()
def run(self): if not self.args: print(self.help()) return # Insert current working directory to the python path to recognize # dependencies to local modules even if cwd is not in the PYTHONPATH. sys.path.insert(0, os.getcwd()) try: project = self.manager.project_from_files(self.args) linker = Linker(project, tag=True) handler = DiadefsHandler(self.config) diadefs = handler.get_diadefs(project, linker) finally: sys.path.pop(0) return diadefs
def run(self, args): """checking arguments and run project""" if not args: print(self.help()) return 1 with fix_import_path(args): project = project_from_files( args, project_name=self.config.project, black_list=self.config.ignore_list, ) linker = Linker(project, tag=True) handler = DiadefsHandler(self.config) diadefs = handler.get_diadefs(project, linker) writer.DiagramWriter(self.config).write(diadefs) return 0
def test_property_handling(default_config: PyreverseConfig, get_project: Callable) -> None: project = get_project("data.property_pattern") class_diagram = DefaultDiadefGenerator( Linker(project), DiadefsHandler(default_config)).visit(project)[0] obj = class_diagram.classe("PropertyPatterns") assert len(class_diagram.get_methods(obj.node)) == 0 assert class_diagram.get_attrs(obj.node) == ["prop1", "prop2"]
def setUpClass(cls): project = get_project(os.path.join(os.path.dirname(__file__), 'data')) linker = Linker(project) handler = DiadefsHandler(CONFIG) dd = DefaultDiadefGenerator(linker, handler).visit(project) for diagram in dd: diagram.extract_relationships() writer = DotWriter(CONFIG) writer.write(dd)
def setUpClass(cls): project = get_project(cls.datadir) linker = Linker(project) handler = DiadefsHandler(CONFIG) dd = DefaultDiadefGenerator(linker, handler).visit(project) for diagram in dd: diagram.extract_relationships() writer = DotWriter(CONFIG) writer.write(dd)
def setUpClass(cls): project = get_project(os.path.join(os.path.dirname(__file__), 'data')) linker = Linker(project) handler = DiadefsHandler(CONFIG) cls.dd = DefaultDiadefGenerator(linker, handler).visit(project) for diagram in cls.dd: diagram.extract_relationships() cls.writer = DotWriter(STDOUT_CONFIG) cls.package_diagram = cls.dd[0] cls.class_diagram = cls.dd[1]
def _setup(project: Project, config: PyreverseConfig, writer: DiagramWriter) -> Iterator: linker = Linker(project) handler = DiadefsHandler(config) dd = DefaultDiadefGenerator(linker, handler).visit(project) for diagram in dd: diagram.extract_relationships() writer.write(dd) yield for fname in (DOT_FILES + COLORIZED_DOT_FILES + VCG_FILES + PUML_FILES + COLORIZED_PUML_FILES + MMD_FILES + HTML_FILES): try: os.remove(fname) except FileNotFoundError: continue
def setup(): project = get_project(os.path.join(os.path.dirname(__file__), "data")) linker = Linker(project) CONFIG = Config() handler = DiadefsHandler(CONFIG) dd = DefaultDiadefGenerator(linker, handler).visit(project) for diagram in dd: diagram.extract_relationships() writer = DotWriter(CONFIG) writer.write(dd) yield for fname in DOT_FILES: try: os.remove(fname) except: continue
def run(self, args): """checking arguments and run project""" if not args: print self.help() return project = self.manager.project_from_files(args, astng_wrapper) self.project = project linker = NoInferLinker(project, tag=True) handler = DiadefsHandler(self.config) diadefs = handler.get_diadefs(project, linker) # Add inheritance information to nodes # csu_parents will contain links to all parents of class for rel in diadefs[-1].relationships['specialization']: if hasattr(rel.from_object, "csu_parents"): rel.from_object.csu_parents.append(rel.to_object) else: rel.from_object.csu_parents=[rel.to_object] bad_ducks = 0 empty_ducks = 0 # First pass for collecting "duck" information about fields for obj in diadefs[-1].objects: self._compute_signature(obj) attr_names = [re.search('[^ :]*',s).group(0) for s in obj.attrs] self._all_attrs_num += len(Set(attr_names)) attr_names+= [m.name for m in obj.methods] duck_dict = None for meth in obj.methods: # check self access in method and generate information about class attrs if(self._process_candidates): duck_dict = self._extract_duck_info(meth,attr_names,duck_dict) self._processed_methods += 1 # add duck information to classes obj.ducks=duck_dict successes = 0 #Second pass for processing "duck" information and generate information about types for current_class in diadefs[-1].objects: if (current_class.ducks is None): continue for duck in current_class.ducks.keys(): if(current_class.ducks[duck]['complex_type']): self._complex_ducks +=1 #self._found_ducks+=1 # duck is complex type, nothing to do with it # TODO recursively complex types if current_class.ducks[duck].has_key('element_signature'): # search for class of element is needed duck_attrs = current_class.ducks[duck]['element_signature']['attrs'] duck_methods = current_class.ducks[duck]['element_signature']['methods'] else: # duck of complex type and no duck info about element empty_ducks += 1 continue else: duck_attrs = current_class.ducks[duck]['attrs'] duck_methods = current_class.ducks[duck]['methods'] # ignore empty ducks if((not duck_attrs) and (not duck_methods)): empty_ducks += 1 continue duck_found = False for field_candidate in diadefs[-1].objects: complex_type = self._check_complex_type(duck_attrs, duck_methods) if(complex_type): #DEBUG if(current_class.ducks[duck]['complex_type']): if((current_class.ducks[duck]['complex_type'] != complex_type) and (current_class.ducks[duck]['complex_type'] !='Unknown')): print current_class.ducks[duck]['complex_type'], complex_type #END DEBUG current_class.ducks[duck]['complex_type'] = complex_type if(not duck_found): self._found_ducks+=1 duck_found = True if(all(attr in field_candidate.csu_complete_signatures['Attrs'] for attr in duck_attrs) and all(method in field_candidate.csu_complete_signatures['Methods'] for method in duck_methods)): current_class.ducks[duck]['type'].append(field_candidate) successes += 1 self._prob_used_classes |= Set([field_candidate.fig_id]) if(not duck_found): self._found_ducks+=1 duck_found = True #check if duck not found at all if(not duck_found): bad_ducks += 1 print "Bad duck - ",duck_attrs, duck_methods print "Bad ducks ", bad_ducks print "Empty ducks ", empty_ducks print "Numbers of ducks: ", self._ducks_count print "Numbers of ducks with assignment in class: ", self._assigned_ducks print "Numbers of ducks with complex type: ", self._complex_ducks print "Found ducks: ",self._found_ducks, " percentage: ",round(100*float(self._found_ducks)/self._ducks_count,1), " %" print "Numbers of all attributes in project: ", self._all_attrs_num, " percentage of found attrs: ",round(100*float(self._found_ducks)/self._all_attrs_num,1), " %" print "Numbers of classes: ",len(diadefs[-1].objects) print "Probably used (as field) classes: ",len(self._prob_used_classes)," percentage: ",round(100*float(len(self._prob_used_classes))/len(diadefs[-1].objects),1), " %" print "Processed methods: ", self._processed_methods """ result XML generation """ mapper = {} root = etree.Element("Classes") for obj in diadefs[-1].objects: self._all_classes +=1 node = etree.Element("Class",name=obj.title,id=str(obj.fig_id),label=obj.node.root().name) mapper[obj] = node root.append(node) for attrname in Set([re.search('[^ :]*',attr).group(0) for attr in obj.attrs]): attr_node = etree.Element('Attr',name=attrname,modifier='public') node.append(attr_node) if(obj.ducks and (attrname in obj.ducks)): if obj.ducks[attrname]['complex_type']: for prob_type in obj.ducks[attrname]['type']: attr_node.append(etree.Element('AggregatedType',type=str(obj.ducks[attrname]['complex_type']),element=prob_type.title,id=str(prob_type.fig_id))) else: for prob_type in obj.ducks[attrname]['type']: attr_node.append(etree.Element('CommonType',name=prob_type.title,id=str(prob_type.fig_id))) for meth in obj.methods: meth_node = etree.Element('Method',name=meth.name,modifier='public') # This is needed for some native libs(pyx) if(meth.args.args == None): continue for arg in meth.args.args: # ignore self arg if not arg.name == 'self': meth_node.append(etree.Element('Arg',name=arg.name)) node.append(meth_node) for rel in diadefs[-1].relationships['specialization']: mapper[rel.from_object].append(etree.Element('Parent',name=rel.to_object.title,id=str(rel.to_object.fig_id))) f = open('test.xml','w') f.write(etree.tostring(root, pretty_print=True, encoding='utf-8', xml_declaration=True)) f.close() print len(diadefs[-1].relationships['specialization']) #print self._good_gettatr,self._bad_gettatr #print self._all_ducks #print self._all_classes
def HANDLER(default_config: PyreverseConfig) -> DiadefsHandler: return DiadefsHandler(default_config)
from logilab.common.testlib import TestCase, unittest_main from pylint.pyreverse.diadefslib import DefaultDiadefGenerator, DiadefsHandler from pylint.pyreverse.diagrams import set_counter from pylint.pyreverse.writer import DotWriter from pylint.pyreverse.utils import get_visibility from utils import FileTC, build_file_case, get_project, Config project = get_project('data') linker = Linker(project) set_counter(0) config = Config() handler = DiadefsHandler(config) dd = DefaultDiadefGenerator(linker, handler).visit(project) for diagram in dd: diagram.extract_relationships() class DotWriterTC(FileTC): generated_files = ( 'packages_No_Name.dot', 'classes_No_Name.dot', ) def setUp(self): FileTC.setUp(self) writer = DotWriter(config)
def HANDLER(): return DiadefsHandler(Config())