|
1 # Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. |
|
2 # This component and the accompanying materials are made available under the terms of the License |
|
3 # "Eclipse Public License v1.0" which accompanies this distribution, |
|
4 # and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
5 # |
|
6 # Initial Contributors: |
|
7 # Nokia Corporation - initial contribution. |
|
8 # |
|
9 # Contributors: |
|
10 # |
|
11 # Description: |
|
12 # |
|
13 import unittest |
|
14 import sys |
|
15 from cStringIO import StringIO |
|
16 from optparse import OptionParser |
|
17 from xml.etree import ElementTree as etree |
|
18 import os.path |
|
19 import logging |
|
20 import shutil |
|
21 from guidiser import Guidiser |
|
22 |
|
23 __version__ = "0.1" |
|
24 |
|
25 |
|
26 class LinkFile(object): |
|
27 """ |
|
28 Parses string representations of cxxapiref XML files and returns an updated |
|
29 string representation with inserted ids for linking to cxxFunctions. |
|
30 """ |
|
31 |
|
32 def __init__(self, guidise=False): |
|
33 self.guidiser = Guidiser() |
|
34 self.guidise = guidise |
|
35 def _get_cxxfunction_elems(self, elem): |
|
36 """ |
|
37 Takes an elements and generates a list of all child elements that are called cxxFunction |
|
38 """ |
|
39 return [e for e in elem.getiterator() if e.tag == "cxxFunction"] |
|
40 |
|
41 def _get_funcs_with_no_params(self, func_elem_list): |
|
42 """ |
|
43 Takes a list of cxxFunction elements and returns a list of those with no parameters. |
|
44 """ |
|
45 no_params = [] |
|
46 for func in func_elem_list: |
|
47 apiname = func.find("apiName").text |
|
48 params_elem = func.find("cxxFunctionDetail/cxxFunctionDefinition/cxxFunctionParameters") |
|
49 # if cxxFunctionParameters has no children |
|
50 if len(params_elem.getiterator()) == 1: |
|
51 no_params.append(apiname) |
|
52 return no_params |
|
53 |
|
54 |
|
55 def _filter_funcs_with_no_params(self, func_elem_list): |
|
56 """ |
|
57 Takes a list of cxxFunction elements and returns a list with parameterless functions |
|
58 and all of their overloads removed. |
|
59 """ |
|
60 no_param_funcs = self._get_funcs_with_no_params(func_elem_list) |
|
61 return [func_elem for func_elem in func_elem_list if not func_elem.find("apiName").text in no_param_funcs] |
|
62 |
|
63 def _filter_duplicate_funcs(self, func_elem_list): |
|
64 """ |
|
65 Takes a list of cxxFunction elements and returns a list ones with unique apiName text. |
|
66 In the case of overloads the first instance found is taken and the rest are filtered. |
|
67 """ |
|
68 seen_func_names = [] |
|
69 filtered = [] |
|
70 for func_elem in func_elem_list: |
|
71 this_apiname = func_elem.find("apiName").text |
|
72 if not this_apiname in seen_func_names: |
|
73 filtered.append(func_elem) |
|
74 seen_func_names.append(this_apiname) |
|
75 return filtered |
|
76 |
|
77 def _insert_id_into_cxxfunction_apiname(self, func_elem): |
|
78 """ |
|
79 Takes a cxxFunction element. Returns the element with an id inserted into the child apiName element. |
|
80 """ |
|
81 function_scoped_name=func_elem.find("cxxFunctionDetail/cxxFunctionDefinition/cxxFunctionScopedName").text |
|
82 |
|
83 if function_scoped_name == None: |
|
84 function_scoped_name = "" |
|
85 else: |
|
86 function_scoped_name+="::" |
|
87 |
|
88 apiname_id = "".join([function_scoped_name,func_elem.find("apiName").text,"()"]) |
|
89 |
|
90 if self.guidise: |
|
91 apiname_id = self.guidiser._get_guid(apiname_id) |
|
92 |
|
93 func_elem.find("apiName").attrib["id"] = apiname_id |
|
94 return func_elem |
|
95 |
|
96 def get_func_elems_to_linkify(self, root): |
|
97 cxxfunction_elems = self._get_cxxfunction_elems(root) |
|
98 cxxfunction_elems = self._filter_funcs_with_no_params(cxxfunction_elems) |
|
99 cxxfunction_elems = self._filter_duplicate_funcs(cxxfunction_elems) |
|
100 return cxxfunction_elems |
|
101 |
|
102 def get_linkified(self, file_as_string): |
|
103 """ |
|
104 Takes a string representation of a cxxapiref file and returns the string |
|
105 with inserted cxxFunction ids for any functions that fit the insertion rule. |
|
106 |
|
107 The id insertion rule is: |
|
108 |
|
109 If a function and none of its overloads have no arguments then insert an |
|
110 id that represents a function with no arguments over the first function definition encountered. |
|
111 The id is inserted into the apiName child element of the function. |
|
112 """ |
|
113 try: |
|
114 root = etree.fromstring(file_as_string) |
|
115 except Exception, e: |
|
116 raise Exception("Failed to parse string as xml file error was %s" % e) |
|
117 funcs_to_linkify = self.get_func_elems_to_linkify(root) |
|
118 for index in xrange(0, len(funcs_to_linkify)): |
|
119 func = self._insert_id_into_cxxfunction_apiname(funcs_to_linkify[index]) |
|
120 return etree.tostring(root) |
|
121 |
|
122 |
|
123 class LinkInserter(object): |
|
124 |
|
125 def __init__(self, link_file): |
|
126 self.link_file = link_file |
|
127 |
|
128 def _handle_xml_file(self, xml_file): |
|
129 """ |
|
130 Runs linkify function on each file and writes the result to disk |
|
131 """ |
|
132 logging.info("Inserting links into %s" % xml_file) |
|
133 content = open(xml_file, "r").read() |
|
134 try: |
|
135 linkified_contents = self.link_file.get_linkified(content) |
|
136 except Exception,e: |
|
137 logging.error("%s %s" %(e, xml_file)) |
|
138 return |
|
139 |
|
140 try: |
|
141 f = open(xml_file, "w") |
|
142 except Exception, e: |
|
143 raise IOError("Could not open xml file %s for writing, error was: %s" % (xml_file, e)) |
|
144 else: |
|
145 f.write(linkified_contents) |
|
146 f.close() |
|
147 |
|
148 def _handle_xml_files(self, xml_files): |
|
149 """ |
|
150 Iterates over a list of files and calls _handle_xml_file on them |
|
151 """ |
|
152 for xml_file in xml_files: |
|
153 self._handle_xml_file(xml_file) |
|
154 |
|
155 def _do_linkifying(self, dir): |
|
156 """ |
|
157 Takes a directory and calls a handler function on a list of xml files in that and sub directories. |
|
158 """ |
|
159 for root, dirs, files in os.walk(dir): |
|
160 xml_file_paths = [os.path.join(root, f) for f in os.listdir(root) if os.path.splitext(f)[1].lower() == (".xml")] |
|
161 self._handle_xml_files(xml_file_paths) |
|
162 |
|
163 def linkify_dir(self, dir): |
|
164 if not os.path.exists(os.path.abspath(dir)): |
|
165 raise IOError("Directory to linkify does not exist: %s" % dir) |
|
166 self._do_linkifying(dir) |
|
167 |
|
168 |
|
169 def insertlinks(xml_dir): |
|
170 link_inserter = LinkInserter(LinkFile(guidise=True)) |
|
171 link_inserter.linkify_dir(xml_dir) |
|
172 |
|
173 |
|
174 def main(): |
|
175 usage = "usage: %prog <Path to the XML content>" |
|
176 parser = OptionParser(usage, version='%prog ' + __version__) |
|
177 (options, args) = parser.parse_args() |
|
178 if len(args) < 1: |
|
179 parser.print_help() |
|
180 parser.error("Please supply the path to the XML content") |
|
181 insertlinks(args[0]) |
|
182 |
|
183 |
|
184 if __name__ == '__main__': |
|
185 sys.exit(main()) |
|
186 |
|
187 |
|
188 ###################################### |
|
189 # Test code |
|
190 ###################################### |
|
191 |
|
192 class TestLinkFile(unittest.TestCase): |
|
193 |
|
194 def setUp(self): |
|
195 self.link_file = LinkFile() |
|
196 |
|
197 def test__get_funcs_with_no_params(self): |
|
198 func = """ |
|
199 <cxxClass><cxxFunction id="class_b_trace_1a7217f2fa88e99af3dbb5827fdc8507b7"> |
|
200 <apiName>Init0</apiName> |
|
201 <cxxFunctionDetail> |
|
202 <cxxFunctionDefinition> |
|
203 <cxxFunctionParameters/> |
|
204 </cxxFunctionDefinition> |
|
205 </cxxFunctionDetail> |
|
206 </cxxFunction></cxxClass> |
|
207 """ |
|
208 root = etree.fromstring(func) |
|
209 func_list = [e for e in root.getiterator() if e.tag == "cxxFunction"] |
|
210 expected = ["Init0"] |
|
211 returned = self.link_file._get_funcs_with_no_params(func_list) |
|
212 self.assertEqual(expected, returned) |
|
213 |
|
214 def test__get_funcs_with_no_params_ignores_a_func_with_params(self): |
|
215 func = """ |
|
216 <cxxClass><cxxFunction id="class_b_trace_1a7217f2fa88e99af3dbb5827fdc8507b7"> |
|
217 <apiName>Init0</apiName> |
|
218 <cxxFunctionDetail> |
|
219 <cxxFunctionDefinition> |
|
220 <cxxFunctionParameters> |
|
221 <cxxFunctionParameter> |
|
222 <cxxFunctionParameterDeclaredType> |
|
223 <apiRelation keyref="_always_online_manager_client_8cpp_1a8240e11f17c80b6b222fc2af50234da4">TUint32</apiRelation> |
|
224 </cxxFunctionParameterDeclaredType> |
|
225 <cxxFunctionParameterDeclarationName>a0</cxxFunctionParameterDeclarationName> |
|
226 <apiDefNote/> |
|
227 </cxxFunctionParameter> |
|
228 </cxxFunctionParameters> |
|
229 </cxxFunctionDefinition> |
|
230 </cxxFunctionDetail> |
|
231 </cxxFunction></cxxClass> |
|
232 """ |
|
233 root = etree.fromstring(func) |
|
234 func_list = [e for e in root.getiterator() if e.tag == "cxxFunction"] |
|
235 expected = [] |
|
236 returned = self.link_file._get_funcs_with_no_params(func_list) |
|
237 self.assertEqual(expected, returned) |
|
238 |
|
239 def test_filter_duplicate_funcs_ignores_duplicate_funcs(self): |
|
240 func = """ |
|
241 <cxxClass> |
|
242 <cxxFunction id="class_b_trace_1a7217f2fa88e99af3dbb5827fdc8507b7"> |
|
243 <apiName>Init0</apiName> |
|
244 </cxxFunction> |
|
245 <cxxFunction id="class_b_trace_1a7217f2fa88e99af3dbb5827fdc8507b7"> |
|
246 <apiName>Init0</apiName> |
|
247 </cxxFunction> |
|
248 </cxxClass> |
|
249 """ |
|
250 root = etree.fromstring(func) |
|
251 func_list = [e for e in root.getiterator() if e.tag == "cxxFunction"] |
|
252 expected = [func_list[0]] |
|
253 returned = self.link_file._filter_duplicate_funcs(func_list) |
|
254 self.assertEqual(expected, returned) |
|
255 |
|
256 def test__filter_funcs_with_no_params_filters_funcs_with_no_params(self): |
|
257 func = """ |
|
258 <cxxClass> |
|
259 <cxxFunction id="class_b_trace_1a7217f2fa88e99af3dbb5827fdc8507b7"> |
|
260 <apiName>Init0</apiName> |
|
261 <cxxFunctionDetail> |
|
262 <cxxFunctionDefinition> |
|
263 <cxxFunctionParameters/> |
|
264 </cxxFunctionDefinition> |
|
265 </cxxFunctionDetail> |
|
266 </cxxFunction> |
|
267 <cxxFunction id="class_b_trace_1a7217f2fa88e99af3dbb5827fdc8507b7"> |
|
268 <apiName>Init1</apiName> |
|
269 <cxxFunctionDetail> |
|
270 <cxxFunctionDefinition> |
|
271 <cxxFunctionParameters> |
|
272 <cxxFunctionParameter> |
|
273 <cxxFunctionParameterDeclaredType> |
|
274 <apiRelation keyref="_always_online_manager_client_8cpp_1a8240e11f17c80b6b222fc2af50234da4">TUint32</apiRelation> |
|
275 </cxxFunctionParameterDeclaredType> |
|
276 <cxxFunctionParameterDeclarationName>a0</cxxFunctionParameterDeclarationName> |
|
277 <apiDefNote/> |
|
278 </cxxFunctionParameter> |
|
279 </cxxFunctionParameters> |
|
280 </cxxFunctionDefinition> |
|
281 </cxxFunctionDetail> |
|
282 </cxxFunction> |
|
283 </cxxClass> |
|
284 """ |
|
285 root = etree.fromstring(func) |
|
286 func_list = [e for e in root.getiterator() if e.tag == "cxxFunction"] |
|
287 expected = [func_list[1]] |
|
288 returned = self.link_file._filter_funcs_with_no_params(func_list) |
|
289 self.assertEqual(expected, returned) |
|
290 |
|
291 def test__insert_id_into_cxxfunction_apiname(self): |
|
292 func_str = """<cxxFunction id="class_b_trace_1a7217f2fa88e99af3dbb5827fdc8507b7"> |
|
293 <apiName>Init0</apiName> |
|
294 <shortdesc/> |
|
295 <cxxFunctionDetail> |
|
296 <cxxFunctionDefinition> |
|
297 <cxxFunctionAccessSpecifier value="public"/> |
|
298 <cxxFunctionStorageClassSpecifierStatic/> |
|
299 <cxxFunctionDeclaredType>void</cxxFunctionDeclaredType> |
|
300 <cxxFunctionScopedName>BTrace</cxxFunctionScopedName> |
|
301 <cxxFunctionPrototype>static void Init0(TUint32 a0)</cxxFunctionPrototype> |
|
302 <cxxFunctionNameLookup>BTrace::Init0(TUint32 a0)</cxxFunctionNameLookup> |
|
303 <cxxFunctionParameters> |
|
304 <cxxFunctionParameter> |
|
305 <cxxFunctionParameterDeclaredType> |
|
306 <apiRelation keyref="_always_online_manager_client_8cpp_1a8240e11f17c80b6b222fc2af50234da4">TUint32</apiRelation> |
|
307 </cxxFunctionParameterDeclaredType> |
|
308 <cxxFunctionParameterDeclarationName>a0</cxxFunctionParameterDeclarationName> |
|
309 <apiDefNote/> |
|
310 </cxxFunctionParameter> |
|
311 </cxxFunctionParameters> |
|
312 <cxxFunctionAPIItemLocation> |
|
313 <cxxFunctionDeclarationFile name="filePath" value="D:/epoc32/include/e32btrace.h"/> |
|
314 <cxxFunctionDeclarationFileLine name="lineNumber" value="3882"/> |
|
315 <cxxFunctionDefinitionFile name="filePath" value="D:/EPOC/master/sf/mw/messagingmw/messagingfw/alwaysonline/AlwaysOnlineManager/src/AlwaysOnlineManagerClient.cpp"/> |
|
316 <cxxFunctionDefinitionFileLineStart name="lineNumber" value="-1"/> |
|
317 <cxxFunctionDefinitionFileLineEnd name="lineNumber" value="-1"/> |
|
318 </cxxFunctionAPIItemLocation> |
|
319 </cxxFunctionDefinition> |
|
320 <apiDesc/> |
|
321 </cxxFunctionDetail> |
|
322 </cxxFunction>""" |
|
323 func_elem = etree.fromstring(func_str) |
|
324 returned = self.link_file._insert_id_into_cxxfunction_apiname(func_elem) |
|
325 self.assertEquals(returned.find("apiName").attrib["id"], "BTrace::Init0()") |
|
326 |
|
327 def test__insert_id_into_cxxfunction_apiname_when_the_cxxfunction_has_no_scoped_name(self): |
|
328 func_str = """<cxxFunction id="class_b_trace_1a7217f2fa88e99af3dbb5827fdc8507b7"> |
|
329 <apiName>Init0</apiName> |
|
330 <shortdesc/> |
|
331 <cxxFunctionDetail> |
|
332 <cxxFunctionDefinition> |
|
333 <cxxFunctionAccessSpecifier value="public"/> |
|
334 <cxxFunctionStorageClassSpecifierStatic/> |
|
335 <cxxFunctionDeclaredType>void</cxxFunctionDeclaredType> |
|
336 <cxxFunctionScopedName/> |
|
337 <cxxFunctionPrototype>static void Init0(TUint32 a0)</cxxFunctionPrototype> |
|
338 <cxxFunctionNameLookup>BTrace::Init0(TUint32 a0)</cxxFunctionNameLookup> |
|
339 <cxxFunctionParameters> |
|
340 <cxxFunctionParameter> |
|
341 <cxxFunctionParameterDeclaredType> |
|
342 <apiRelation keyref="_always_online_manager_client_8cpp_1a8240e11f17c80b6b222fc2af50234da4">TUint32</apiRelation> |
|
343 </cxxFunctionParameterDeclaredType> |
|
344 <cxxFunctionParameterDeclarationName>a0</cxxFunctionParameterDeclarationName> |
|
345 <apiDefNote/> |
|
346 </cxxFunctionParameter> |
|
347 </cxxFunctionParameters> |
|
348 <cxxFunctionAPIItemLocation> |
|
349 <cxxFunctionDeclarationFile name="filePath" value="D:/epoc32/include/e32btrace.h"/> |
|
350 <cxxFunctionDeclarationFileLine name="lineNumber" value="3882"/> |
|
351 <cxxFunctionDefinitionFile name="filePath" value="D:/EPOC/master/sf/mw/messagingmw/messagingfw/alwaysonline/AlwaysOnlineManager/src/AlwaysOnlineManagerClient.cpp"/> |
|
352 <cxxFunctionDefinitionFileLineStart name="lineNumber" value="-1"/> |
|
353 <cxxFunctionDefinitionFileLineEnd name="lineNumber" value="-1"/> |
|
354 </cxxFunctionAPIItemLocation> |
|
355 </cxxFunctionDefinition> |
|
356 <apiDesc/> |
|
357 </cxxFunctionDetail> |
|
358 </cxxFunction>""" |
|
359 func_elem = etree.fromstring(func_str) |
|
360 returned = self.link_file._insert_id_into_cxxfunction_apiname(func_elem) |
|
361 self.assertEquals(returned.find("apiName").attrib["id"], "Init0()") |
|
362 |
|
363 def test_i_can_insert_an_id_to_a_cxxfunction_apiname(self): |
|
364 file_as_string = """ |
|
365 <cxxClass> |
|
366 <cxxFunction id="class_b_trace_1a7217f2fa88e99af3dbb5827fdc8507b7"> |
|
367 <apiName>Init0</apiName> |
|
368 <shortdesc/> |
|
369 <cxxFunctionDetail> |
|
370 <cxxFunctionDefinition> |
|
371 <cxxFunctionAccessSpecifier value="public"/> |
|
372 <cxxFunctionStorageClassSpecifierStatic/> |
|
373 <cxxFunctionDeclaredType>void</cxxFunctionDeclaredType> |
|
374 <cxxFunctionScopedName>BTrace</cxxFunctionScopedName> |
|
375 <cxxFunctionPrototype>static void Init0(TUint32 a0)</cxxFunctionPrototype> |
|
376 <cxxFunctionNameLookup>BTrace::Init0(TUint32 a0)</cxxFunctionNameLookup> |
|
377 <cxxFunctionParameters> |
|
378 <cxxFunctionParameter> |
|
379 <cxxFunctionParameterDeclaredType> |
|
380 <apiRelation keyref="_always_online_manager_client_8cpp_1a8240e11f17c80b6b222fc2af50234da4">TUint32</apiRelation> |
|
381 </cxxFunctionParameterDeclaredType> |
|
382 <cxxFunctionParameterDeclarationName>a0</cxxFunctionParameterDeclarationName> |
|
383 <apiDefNote/> |
|
384 </cxxFunctionParameter> |
|
385 </cxxFunctionParameters> |
|
386 <cxxFunctionAPIItemLocation> |
|
387 <cxxFunctionDeclarationFile name="filePath" value="D:/epoc32/include/e32btrace.h"/> |
|
388 <cxxFunctionDeclarationFileLine name="lineNumber" value="3882"/> |
|
389 <cxxFunctionDefinitionFile name="filePath" value="D:/EPOC/master/sf/mw/messagingmw/messagingfw/alwaysonline/AlwaysOnlineManager/src/AlwaysOnlineManagerClient.cpp"/> |
|
390 <cxxFunctionDefinitionFileLineStart name="lineNumber" value="-1"/> |
|
391 <cxxFunctionDefinitionFileLineEnd name="lineNumber" value="-1"/> |
|
392 </cxxFunctionAPIItemLocation> |
|
393 </cxxFunctionDefinition> |
|
394 <apiDesc/> |
|
395 </cxxFunctionDetail> |
|
396 </cxxFunction> |
|
397 </cxxClass>""" |
|
398 returned = self.link_file.get_linkified(file_as_string) |
|
399 self.assertEquals(etree.fromstring(returned).find("cxxFunction/apiName").attrib["id"], "BTrace::Init0()") |
|
400 |
|
401 |
|
402 def test__insert_a_guidised_id_into_cxxfunction_apiname(self): |
|
403 self.link_file = LinkFile(guidise=True) |
|
404 func_str = """<cxxFunction id="class_b_trace_1a7217f2fa88e99af3dbb5827fdc8507b7"> |
|
405 <apiName>Init0</apiName> |
|
406 <shortdesc/> |
|
407 <cxxFunctionDetail> |
|
408 <cxxFunctionDefinition> |
|
409 <cxxFunctionAccessSpecifier value="public"/> |
|
410 <cxxFunctionStorageClassSpecifierStatic/> |
|
411 <cxxFunctionDeclaredType>void</cxxFunctionDeclaredType> |
|
412 <cxxFunctionScopedName>BTrace</cxxFunctionScopedName> |
|
413 <cxxFunctionPrototype>static void Init0(TUint32 a0)</cxxFunctionPrototype> |
|
414 <cxxFunctionNameLookup>BTrace::Init0(TUint32 a0)</cxxFunctionNameLookup> |
|
415 <cxxFunctionParameters> |
|
416 <cxxFunctionParameter> |
|
417 <cxxFunctionParameterDeclaredType> |
|
418 <apiRelation keyref="_always_online_manager_client_8cpp_1a8240e11f17c80b6b222fc2af50234da4">TUint32</apiRelation> |
|
419 </cxxFunctionParameterDeclaredType> |
|
420 <cxxFunctionParameterDeclarationName>a0</cxxFunctionParameterDeclarationName> |
|
421 <apiDefNote/> |
|
422 </cxxFunctionParameter> |
|
423 </cxxFunctionParameters> |
|
424 <cxxFunctionAPIItemLocation> |
|
425 <cxxFunctionDeclarationFile name="filePath" value="D:/epoc32/include/e32btrace.h"/> |
|
426 <cxxFunctionDeclarationFileLine name="lineNumber" value="3882"/> |
|
427 <cxxFunctionDefinitionFile name="filePath" value="D:/EPOC/master/sf/mw/messagingmw/messagingfw/alwaysonline/AlwaysOnlineManager/src/AlwaysOnlineManagerClient.cpp"/> |
|
428 <cxxFunctionDefinitionFileLineStart name="lineNumber" value="-1"/> |
|
429 <cxxFunctionDefinitionFileLineEnd name="lineNumber" value="-1"/> |
|
430 </cxxFunctionAPIItemLocation> |
|
431 </cxxFunctionDefinition> |
|
432 <apiDesc/> |
|
433 </cxxFunctionDetail> |
|
434 </cxxFunction>""" |
|
435 func_elem = etree.fromstring(func_str) |
|
436 returned = self.link_file._insert_id_into_cxxfunction_apiname(func_elem) |
|
437 self.assertEquals(returned.find("apiName").attrib["id"], "GUID-C8A77671-4E2F-3290-9592-84A70B14F88D") |
|
438 |
|
439 def test__insert_a_guidised_id_into_cxxfunction_apiname_when_the_cxxfunction_has_no_scoped_name(self): |
|
440 self.link_file = LinkFile(guidise=True) |
|
441 func_str = """<cxxFunction id="class_b_trace_1a7217f2fa88e99af3dbb5827fdc8507b7"> |
|
442 <apiName>Init0</apiName> |
|
443 <shortdesc/> |
|
444 <cxxFunctionDetail> |
|
445 <cxxFunctionDefinition> |
|
446 <cxxFunctionAccessSpecifier value="public"/> |
|
447 <cxxFunctionStorageClassSpecifierStatic/> |
|
448 <cxxFunctionDeclaredType>void</cxxFunctionDeclaredType> |
|
449 <cxxFunctionScopedName/> |
|
450 <cxxFunctionPrototype>static void Init0(TUint32 a0)</cxxFunctionPrototype> |
|
451 <cxxFunctionNameLookup>BTrace::Init0(TUint32 a0)</cxxFunctionNameLookup> |
|
452 <cxxFunctionParameters> |
|
453 <cxxFunctionParameter> |
|
454 <cxxFunctionParameterDeclaredType> |
|
455 <apiRelation keyref="_always_online_manager_client_8cpp_1a8240e11f17c80b6b222fc2af50234da4">TUint32</apiRelation> |
|
456 </cxxFunctionParameterDeclaredType> |
|
457 <cxxFunctionParameterDeclarationName>a0</cxxFunctionParameterDeclarationName> |
|
458 <apiDefNote/> |
|
459 </cxxFunctionParameter> |
|
460 </cxxFunctionParameters> |
|
461 <cxxFunctionAPIItemLocation> |
|
462 <cxxFunctionDeclarationFile name="filePath" value="D:/epoc32/include/e32btrace.h"/> |
|
463 <cxxFunctionDeclarationFileLine name="lineNumber" value="3882"/> |
|
464 <cxxFunctionDefinitionFile name="filePath" value="D:/EPOC/master/sf/mw/messagingmw/messagingfw/alwaysonline/AlwaysOnlineManager/src/AlwaysOnlineManagerClient.cpp"/> |
|
465 <cxxFunctionDefinitionFileLineStart name="lineNumber" value="-1"/> |
|
466 <cxxFunctionDefinitionFileLineEnd name="lineNumber" value="-1"/> |
|
467 </cxxFunctionAPIItemLocation> |
|
468 </cxxFunctionDefinition> |
|
469 <apiDesc/> |
|
470 </cxxFunctionDetail> |
|
471 </cxxFunction>""" |
|
472 func_elem = etree.fromstring(func_str) |
|
473 returned = self.link_file._insert_id_into_cxxfunction_apiname(func_elem) |
|
474 self.assertEquals(returned.find("apiName").attrib["id"], "GUID-76C4A377-8597-3952-9E6B-3E61D068EE38") |
|
475 |
|
476 def test_i_can_insert_a_guidised_id_to_a_cxxfunction_apiname(self): |
|
477 self.link_file = LinkFile(guidise=True) |
|
478 file_as_string = """ |
|
479 <cxxClass> |
|
480 <cxxFunction id="class_b_trace_1a7217f2fa88e99af3dbb5827fdc8507b7"> |
|
481 <apiName>Init0</apiName> |
|
482 <shortdesc/> |
|
483 <cxxFunctionDetail> |
|
484 <cxxFunctionDefinition> |
|
485 <cxxFunctionAccessSpecifier value="public"/> |
|
486 <cxxFunctionStorageClassSpecifierStatic/> |
|
487 <cxxFunctionDeclaredType>void</cxxFunctionDeclaredType> |
|
488 <cxxFunctionScopedName>BTrace</cxxFunctionScopedName> |
|
489 <cxxFunctionPrototype>static void Init0(TUint32 a0)</cxxFunctionPrototype> |
|
490 <cxxFunctionNameLookup>BTrace::Init0(TUint32 a0)</cxxFunctionNameLookup> |
|
491 <cxxFunctionParameters> |
|
492 <cxxFunctionParameter> |
|
493 <cxxFunctionParameterDeclaredType> |
|
494 <apiRelation keyref="_always_online_manager_client_8cpp_1a8240e11f17c80b6b222fc2af50234da4">TUint32</apiRelation> |
|
495 </cxxFunctionParameterDeclaredType> |
|
496 <cxxFunctionParameterDeclarationName>a0</cxxFunctionParameterDeclarationName> |
|
497 <apiDefNote/> |
|
498 </cxxFunctionParameter> |
|
499 </cxxFunctionParameters> |
|
500 <cxxFunctionAPIItemLocation> |
|
501 <cxxFunctionDeclarationFile name="filePath" value="D:/epoc32/include/e32btrace.h"/> |
|
502 <cxxFunctionDeclarationFileLine name="lineNumber" value="3882"/> |
|
503 <cxxFunctionDefinitionFile name="filePath" value="D:/EPOC/master/sf/mw/messagingmw/messagingfw/alwaysonline/AlwaysOnlineManager/src/AlwaysOnlineManagerClient.cpp"/> |
|
504 <cxxFunctionDefinitionFileLineStart name="lineNumber" value="-1"/> |
|
505 <cxxFunctionDefinitionFileLineEnd name="lineNumber" value="-1"/> |
|
506 </cxxFunctionAPIItemLocation> |
|
507 </cxxFunctionDefinition> |
|
508 <apiDesc/> |
|
509 </cxxFunctionDetail> |
|
510 </cxxFunction> |
|
511 </cxxClass>""" |
|
512 returned = self.link_file.get_linkified(file_as_string) |
|
513 self.assertEquals(etree.fromstring(returned).find("cxxFunction/apiName").attrib["id"], "GUID-C8A77671-4E2F-3290-9592-84A70B14F88D") |
|
514 |
|
515 basic_class_file_str = """\ |
|
516 <cxxClass> |
|
517 <cxxFunction id="function_id"> |
|
518 <apiName>Init0</apiName> |
|
519 <shortdesc/> |
|
520 <cxxFunctionDetail> |
|
521 <cxxFunctionDefinition> |
|
522 <cxxFunctionAccessSpecifier value="public"/> |
|
523 <cxxFunctionStorageClassSpecifierStatic/> |
|
524 <cxxFunctionDeclaredType>void</cxxFunctionDeclaredType> |
|
525 <cxxFunctionScopedName>BTrace</cxxFunctionScopedName> |
|
526 <cxxFunctionPrototype>static void Init0()</cxxFunctionPrototype> |
|
527 <cxxFunctionNameLookup>BTrace::Init0()</cxxFunctionNameLookup> |
|
528 <cxxFunctionParameters/> |
|
529 <cxxFunctionAPIItemLocation> |
|
530 <cxxFunctionDeclarationFile name="filePath" value="D:/epoc32/include/e32btrace.h"/> |
|
531 <cxxFunctionDeclarationFileLine name="lineNumber" value="3882"/> |
|
532 <cxxFunctionDefinitionFile name="filePath" value="D:/EPOC/master/sf/mw/messagingmw/messagingfw/alwaysonline/AlwaysOnlineManager/src/AlwaysOnlineManagerClient.cpp"/> |
|
533 <cxxFunctionDefinitionFileLineStart name="lineNumber" value="-1"/> |
|
534 <cxxFunctionDefinitionFileLineEnd name="lineNumber" value="-1"/> |
|
535 </cxxFunctionAPIItemLocation> |
|
536 </cxxFunctionDefinition> |
|
537 <apiDesc/> |
|
538 </cxxFunctionDetail> |
|
539 </cxxFunction> |
|
540 </cxxClass>""" |
|
541 |
|
542 |
|
543 xml_files = { |
|
544 "basic_xml_file_1.xml": """<tag1></tag1>""", |
|
545 "basic_xml_file_2.xml": """<tag2></tag2>""", |
|
546 } |
|
547 no_xml_files = { |
|
548 "non_xml_file.txt": """Some text""", |
|
549 } |
|
550 |
|
551 |
|
552 class DummyLinkFile(object): |
|
553 |
|
554 def __init__(self): |
|
555 self.visited_files = [] |
|
556 |
|
557 def get_linkified(self, file_as_string): |
|
558 self.visited_files.append(file_as_string) |
|
559 return file_as_string |
|
560 |
|
561 class TestLinkInserter(unittest.TestCase): |
|
562 |
|
563 def setUp(self): |
|
564 self.dummy_link_file = DummyLinkFile() |
|
565 self.inserter = LinkInserter(self.dummy_link_file) |
|
566 |
|
567 def test__handle_xml_file_writes_to_a_file(self): |
|
568 tmp_file_path = os.getcwd() + os.sep + "tmp_file.xml" |
|
569 tmp_file = open(tmp_file_path, "w") |
|
570 tmp_file.write(basic_class_file_str) |
|
571 tmp_file.close() |
|
572 self.inserter._handle_xml_file(tmp_file_path) |
|
573 self.assertEquals(self.dummy_link_file.visited_files, [basic_class_file_str]) |
|
574 os.remove(tmp_file_path) |
|
575 |
|
576 def test_i_raise_an_exception_when_dir_doesnt_exist(self): |
|
577 self.assertRaises(IOError, self.inserter.linkify_dir, "non_existant_dir") |
|
578 |
|
579 def test_i_call_linkify_on_each_file_xml_file_in_a_dir(self): |
|
580 basic_files = {} |
|
581 basic_files.update(xml_files) |
|
582 basic_files.update(no_xml_files) |
|
583 test_dir = os.path.join(os.getcwd(), "test_dir") |
|
584 os.mkdir(test_dir) |
|
585 for filename,file_content in basic_files.items(): |
|
586 handle = open(os.path.join(test_dir, filename),"w") |
|
587 handle.write(file_content) |
|
588 handle.close() |
|
589 self.inserter._do_linkifying(test_dir) |
|
590 self.dummy_link_file.visited_files.sort() |
|
591 xml_files_input = xml_files.values() |
|
592 xml_files_input.sort() |
|
593 self.assertEquals(self.dummy_link_file.visited_files, xml_files_input) |
|
594 shutil.rmtree(test_dir) |