diff -r c4f503f40caf -r 622e59b51640 src/eric7/RemoteServer/EricServerCoverageRequestHandler.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/eric7/RemoteServer/EricServerCoverageRequestHandler.py Thu Feb 15 13:59:02 2024 +0100 @@ -0,0 +1,172 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2024 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the code coverage request handler of the eric-ide server. +""" + +from coverage import Coverage +from coverage.misc import CoverageException + +from eric7.SystemUtilities import FileSystemUtilities + +from .EricRequestCategory import EricRequestCategory + + +class EricServerCoverageRequestHandler: + """ + Class implementing the code coverage request handler of the eric-ide server. + """ + + def __init__(self, server): + """ + Constructor + + @param server reference to the eric-ide server object + @type EricServer + """ + self.__server = server + + self.__requestMethodMapping = { + "LoadData": self.__loadCoverageData, + "AnalyzeFile": self.__analyzeFile, + "AnalyzeFiles": self.__analyzeFiles, + "AnalyzeDirectory": self.__analyzeDirectory, + } + + self.__cover = None + + def handleRequest(self, request, params, reqestUuid): + """ + Public method handling the received file system requests. + + @param request request name + @type str + @param params dictionary containing the request parameters + @type dict + @param reqestUuid UUID of the associated request as sent by the eric IDE + @type str + """ + try: + result = self.__requestMethodMapping[request](params) + self.__server.sendJson( + category=EricRequestCategory.Coverage, + reply=request, + params=result, + reqestUuid=reqestUuid, + ) + + except KeyError: + self.__server.sendJson( + category=EricRequestCategory.Coverage, + reply=request, + params={"Error": f"Request type '{request}' is not supported."}, + ) + + def __loadCoverageData(self, params): + """ + Private method to load the data collected by a code coverage run. + + @param params dictionary containing the request data + @type dict + @return dictionary containing the reply data + @rtype dict + """ + if self.__cover is not None: + del self.__cover + self.__cover = None + + try: + self.__cover = Coverage(data_file=params["data_file"]) + self.__cover.load() + self.__cover.exclude(params["exclude"]) + return {"ok": True} + except CoverageException as err: + return { + "ok": False, + "error": str(err), + } + + def __analyzeFile(self, params): + """ + Private method to analyze a single file. + + @param params dictionary containing the request data + @type dict + @return dictionary containing the reply data + @rtype dict + """ + if self.__cover is None: + return { + "ok": False, + "error": "Coverage data has to be loaded first.", + } + + try: + return { + "ok": True, + "result": self.__cover.analysis2(params["filename"]), + } + except CoverageException as err: + return { + "ok": False, + "error": str(err), + } + + def __analyzeFiles(self, params): + """ + Private method to analyze a list of files. + + @param params dictionary containing the request data + @type dict + @return dictionary containing the reply data + @rtype dict + """ + # TODO: not implemented yet + if self.__cover is None: + return { + "ok": False, + "error": "Coverage data has to be loaded first.", + } + + try: + return { + "ok": True, + "results": [self.__cover.analysis2(f) for f in params["filenames"]], + } + except CoverageException as err: + return { + "ok": False, + "error": str(err), + } + + def __analyzeDirectory(self, params): + """ + Private method to analyze files of a directory tree. + + @param params dictionary containing the request data + @type dict + @return dictionary containing the reply data + @rtype dict + """ + # TODO: not implemented yet + if self.__cover is None: + return { + "ok": False, + "error": "Coverage data has to be loaded first.", + } + + files = FileSystemUtilities.direntries(params["directory"], True, "*.py", False) + + try: + return { + "ok": True, + "results": [self.__cover.analysis2(f) for f in files], + } + except CoverageException as err: + return { + "ok": False, + "error": str(err), + }