|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2024 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the code coverage request handler of the eric-ide server. |
|
8 """ |
|
9 |
|
10 from coverage import Coverage |
|
11 from coverage.misc import CoverageException |
|
12 |
|
13 from eric7.SystemUtilities import FileSystemUtilities |
|
14 |
|
15 from .EricRequestCategory import EricRequestCategory |
|
16 |
|
17 |
|
18 class EricServerCoverageRequestHandler: |
|
19 """ |
|
20 Class implementing the code coverage request handler of the eric-ide server. |
|
21 """ |
|
22 |
|
23 def __init__(self, server): |
|
24 """ |
|
25 Constructor |
|
26 |
|
27 @param server reference to the eric-ide server object |
|
28 @type EricServer |
|
29 """ |
|
30 self.__server = server |
|
31 |
|
32 self.__requestMethodMapping = { |
|
33 "LoadData": self.__loadCoverageData, |
|
34 "AnalyzeFile": self.__analyzeFile, |
|
35 "AnalyzeFiles": self.__analyzeFiles, |
|
36 "AnalyzeDirectory": self.__analyzeDirectory, |
|
37 } |
|
38 |
|
39 self.__cover = None |
|
40 |
|
41 def handleRequest(self, request, params, reqestUuid): |
|
42 """ |
|
43 Public method handling the received file system requests. |
|
44 |
|
45 @param request request name |
|
46 @type str |
|
47 @param params dictionary containing the request parameters |
|
48 @type dict |
|
49 @param reqestUuid UUID of the associated request as sent by the eric IDE |
|
50 @type str |
|
51 """ |
|
52 try: |
|
53 result = self.__requestMethodMapping[request](params) |
|
54 self.__server.sendJson( |
|
55 category=EricRequestCategory.Coverage, |
|
56 reply=request, |
|
57 params=result, |
|
58 reqestUuid=reqestUuid, |
|
59 ) |
|
60 |
|
61 except KeyError: |
|
62 self.__server.sendJson( |
|
63 category=EricRequestCategory.Coverage, |
|
64 reply=request, |
|
65 params={"Error": f"Request type '{request}' is not supported."}, |
|
66 ) |
|
67 |
|
68 def __loadCoverageData(self, params): |
|
69 """ |
|
70 Private method to load the data collected by a code coverage run. |
|
71 |
|
72 @param params dictionary containing the request data |
|
73 @type dict |
|
74 @return dictionary containing the reply data |
|
75 @rtype dict |
|
76 """ |
|
77 if self.__cover is not None: |
|
78 del self.__cover |
|
79 self.__cover = None |
|
80 |
|
81 try: |
|
82 self.__cover = Coverage(data_file=params["data_file"]) |
|
83 self.__cover.load() |
|
84 self.__cover.exclude(params["exclude"]) |
|
85 return {"ok": True} |
|
86 except CoverageException as err: |
|
87 return { |
|
88 "ok": False, |
|
89 "error": str(err), |
|
90 } |
|
91 |
|
92 def __analyzeFile(self, params): |
|
93 """ |
|
94 Private method to analyze a single file. |
|
95 |
|
96 @param params dictionary containing the request data |
|
97 @type dict |
|
98 @return dictionary containing the reply data |
|
99 @rtype dict |
|
100 """ |
|
101 if self.__cover is None: |
|
102 return { |
|
103 "ok": False, |
|
104 "error": "Coverage data has to be loaded first.", |
|
105 } |
|
106 |
|
107 try: |
|
108 return { |
|
109 "ok": True, |
|
110 "result": self.__cover.analysis2(params["filename"]), |
|
111 } |
|
112 except CoverageException as err: |
|
113 return { |
|
114 "ok": False, |
|
115 "error": str(err), |
|
116 } |
|
117 |
|
118 def __analyzeFiles(self, params): |
|
119 """ |
|
120 Private method to analyze a list of files. |
|
121 |
|
122 @param params dictionary containing the request data |
|
123 @type dict |
|
124 @return dictionary containing the reply data |
|
125 @rtype dict |
|
126 """ |
|
127 # TODO: not implemented yet |
|
128 if self.__cover is None: |
|
129 return { |
|
130 "ok": False, |
|
131 "error": "Coverage data has to be loaded first.", |
|
132 } |
|
133 |
|
134 try: |
|
135 return { |
|
136 "ok": True, |
|
137 "results": [self.__cover.analysis2(f) for f in params["filenames"]], |
|
138 } |
|
139 except CoverageException as err: |
|
140 return { |
|
141 "ok": False, |
|
142 "error": str(err), |
|
143 } |
|
144 |
|
145 def __analyzeDirectory(self, params): |
|
146 """ |
|
147 Private method to analyze files of a directory tree. |
|
148 |
|
149 @param params dictionary containing the request data |
|
150 @type dict |
|
151 @return dictionary containing the reply data |
|
152 @rtype dict |
|
153 """ |
|
154 # TODO: not implemented yet |
|
155 if self.__cover is None: |
|
156 return { |
|
157 "ok": False, |
|
158 "error": "Coverage data has to be loaded first.", |
|
159 } |
|
160 |
|
161 files = FileSystemUtilities.direntries(params["directory"], True, "*.py", False) |
|
162 |
|
163 try: |
|
164 return { |
|
165 "ok": True, |
|
166 "results": [self.__cover.analysis2(f) for f in files], |
|
167 } |
|
168 except CoverageException as err: |
|
169 return { |
|
170 "ok": False, |
|
171 "error": str(err), |
|
172 } |