[Epydoc-commits] SF.net SVN: epydoc: [1454] trunk/epydoc/src/epydoc/test/util.py
Brought to you by:
edloper
From: <ed...@us...> - 2007-02-11 05:22:32
|
Revision: 1454 http://svn.sourceforge.net/epydoc/?rev=1454&view=rev Author: edloper Date: 2007-02-10 21:22:31 -0800 (Sat, 10 Feb 2007) Log Message: ----------- - Moved various test functions from doctest files (eg, runbuilder, runparser, etc) to a single epydoc.test.util module, so they can be shared between different doctest files. (E.g., the restructuredtext.doctest file needed to make use of the runbuilder function defined in docbuilder.doctest). Added Paths: ----------- trunk/epydoc/src/epydoc/test/util.py Added: trunk/epydoc/src/epydoc/test/util.py =================================================================== --- trunk/epydoc/src/epydoc/test/util.py (rev 0) +++ trunk/epydoc/src/epydoc/test/util.py 2007-02-11 05:22:31 UTC (rev 1454) @@ -0,0 +1,218 @@ +# +# epydoc -- Utility functions used by regression tests (*.doctest) +# Edward Loper +# +# Created [01/30/01 05:18 PM] +# $Id: html.py 1420 2007-01-28 14:19:30Z dvarrazzo $ +# + +""" +Utility functions used by the regression tests (C{*.doctest}). +""" +__docformat__ = 'epytext en' + +import tempfile, re, os, os.path, textwrap, sys +from epydoc.docbuilder import build_doc, build_doc_index +from epydoc.docparser import parse_docs +from epydoc.docintrospecter import introspect_docs +from epydoc.apidoc import ClassDoc, RoutineDoc +from epydoc.markup import ParsedDocstring +from epydoc.docwriter.html import HTMLWriter + +###################################################################### +#{ Test Functions +###################################################################### + +def runbuilder(s, attribs='', build=None, exclude=''): + """ + This test function takes a string containing the contents of a + module. It writes the string contents to a file, imports the file + as a module, and uses build_doc to build documentation, and pretty + prints the resulting ModuleDoc object. The C{attribs} argument + specifies which attributes of the C{APIDoc}s should be displayed. + The C{build} argument gives the name of a variable in the module + whose documentation should be built, instead of bilding docs for + the whole module. + """ + # Write it to a temp file. + tmp_dir = tempfile.mkdtemp() + out = open(os.path.join(tmp_dir, 'epydoc_test.py'), 'w') + out.write(textwrap.dedent(s)) + out.close() + # Build it. + val_doc = build_doc(os.path.join(tmp_dir, 'epydoc_test.py')) + if build: val_doc = val_doc.variables[build].value + # Display it. + if isinstance(val_doc, ClassDoc): + for val in val_doc.variables.values(): + if isinstance(val.value, RoutineDoc): + fun_to_plain(val.value) + s = val_doc.pp(include=attribs.split(),exclude=exclude.split()) + s = re.sub(r"(filename = ).*", r"\1...", s) + s = re.sub(r"(<module 'epydoc_test' from ).*", r'\1...', s) + s = re.sub(r"(<function \w+ at )0x\w+>", r"\1...>", s) + s = re.sub(r"(<\w+ object at )0x\w+>", r"\1...>", s) + print s + # Clean up. + os.unlink(os.path.join(tmp_dir, 'epydoc_test.py')) + try: os.unlink(os.path.join(tmp_dir, 'epydoc_test.pyc')) + except OSError: pass + os.rmdir(tmp_dir) + del sys.modules['epydoc_test'] + +def runparser(s, attribs='', show=None, exclude=''): + """ + This test function takes a string containing the contents of a + module, and writes it to a file, uses `parse_docs` to parse it, + and pretty prints the resulting ModuleDoc object. The `attribs` + argument specifies which attributes of the `APIDoc`s should be + displayed. The `show` argument, if specifies, gives the name of + the object in the module that should be displayed (but the whole + module will always be inspected; this just selects what to + display). + """ + # Write it to a temp file. + tmp_dir = tempfile.mkdtemp() + out = open(os.path.join(tmp_dir, 'test.py'), 'w') + out.write(textwrap.dedent(s)) + out.close() + # Parse it. + val_doc = parse_docs(out.name) + if show is not None: + for name in show.split('.'): + if isinstance(val_doc, ClassDoc): + val_doc = val_doc.local_variables[name].value + else: + val_doc = val_doc.variables[name].value + # Display it. + s = val_doc.pp(include=attribs.split(), exclude=exclude.split()) + s = re.sub(r"filename = .*", "filename = ...", s) + print s + # Clean up. + os.unlink(os.path.join(tmp_dir, 'test.py')) + os.rmdir(tmp_dir) + +def runintrospecter(s, attribs='', introspect=None, exclude=''): + """ + This test function takes a string containing the contents of a + module. It writes the string contents to a file, imports the file + as a module, and uses C{introspect_docs} to introspect it, and + pretty prints the resulting ModuleDoc object. The C{attribs} + argument specifies which attributes of the C{APIDoc}s should be + displayed. The C{introspect} argument gives the name of a variable + in the module whose value should be introspected, instead of + introspecting the whole module. + """ + # Write it to a temp file. + tmp_dir = tempfile.mkdtemp() + out = open(os.path.join(tmp_dir, 'epydoc_test.py'), 'w') + out.write(textwrap.dedent(s)) + out.close() + # Import it. + sys.path.insert(0, tmp_dir) + if introspect is None: + import epydoc_test as val + else: + exec("from epydoc_test import %s as val" % introspect) + del sys.path[0] + # Introspect it. + val_doc = introspect_docs(val) + # Display it. + s = val_doc.pp(include=attribs.split(),exclude=exclude.split()) + s = re.sub(r"(filename = ).*", r"\1...", s) + s = re.sub(r"(<module 'epydoc_test' from ).*", r'\1...', s) + s = re.sub(r"(<function \w+ at )0x\w+>", r"\1...>", s) + s = re.sub(r"(<\w+ object at )0x\w+>", r"\1...>", s) + print s + # Clean up. + os.unlink(os.path.join(tmp_dir, 'epydoc_test.py')) + try: os.unlink(os.path.join(tmp_dir, 'epydoc_test.pyc')) + except OSError: pass + os.rmdir(tmp_dir) + del sys.modules['epydoc_test'] + +def print_warnings(): + """ + Register a logger that will print warnings & errors. + """ + from epydoc import log + log.register_logger(log.SimpleLogger()) + +def testencoding(s, introspect=True, parse=True, debug=False): + """ + An end-to-end test for unicode encodings. This function takes a + given string, writes it to a python file, and processes that + file's documentation. It then generates HTML output from the + documentation, extracts all docstrings from the generated HTML + output, and displays them. (In order to extract & display all + docstrings, it monkey-patches the HMTLwriter.docstring_to_html() + method.)""" + # Monkey-patch docstring_to_html + original_docstring_to_html = HTMLWriter.docstring_to_html + HTMLWriter.docstring_to_html = print_docstring_as_html + + # Write s to a temporary file. + tmp_dir = tempfile.mkdtemp() + path = os.path.join(tmp_dir, 'enc_test.py') + out = open(path, 'w') + out.write(textwrap.dedent(s)) + out.close() + # Build docs for it + docindex = build_doc_index([path], introspect, parse) + if docindex is None: return + try: del sys.modules['enc_test'] + except: pass + # Write html output. + writer = HTMLWriter(docindex, mark_docstrings=True) + writer.write(tmp_dir) + for file in os.listdir(tmp_dir): + os.unlink(os.path.join(tmp_dir,file)) + os.rmdir(tmp_dir) + + # Restore the HTMLWriter class to its original state. + HTMLWriter.docstring_to_html = original_docstring_to_html + +###################################################################### +#{ Helper Functions +###################################################################### + +def to_plain(docstring): + """Conver a parsed docstring into plain text""" + if isinstance(docstring, ParsedDocstring): + docstring = docstring.to_plaintext(None) + return docstring.rsplit() + +def fun_to_plain(val_doc): + """Convert parsed docstrings in text from a RoutineDoc""" + for k, v in val_doc.arg_types.items(): + val_doc.arg_types[k] = to_plain(v) + for i, (k, v) in enumerate(val_doc.arg_descrs): + val_doc.arg_descrs[i] = (k, to_plain(v)) + +def print_docstring_as_html(self, parsed_docstring, *varargs, **kwargs): + """ + Convert the given parsed_docstring to HTML and print it. Ignore + any other arguments. This function is used by L{testencoding} to + monkey-patch the HTMLWriter class's docstring_to_html() method. + """ + s = parsed_docstring.to_html(None).strip() + s = s.encode('ascii', 'xmlcharrefreplace') + s = remove_surrogates(s) + print s + return '' + +def remove_surrogates(s): + """ + The following is a helper function, used to convert two-character + surrogate sequences into single characters. This is needed + because some systems create surrogates but others don't. + """ + pieces = re.split('(&#\d+;)', s) + for i in range(3, len(pieces)-1, 2): + if pieces[i-1] != '': continue + high,low = int(pieces[i-2][2:-1]), int(pieces[i][2:-1]) + if 0xd800 <= high <= 0xdbff and 0xdc00 <= low <= 0xdfff: + pieces[i-2] = '&#%d;' % (((high&0x3ff)<<10) + + (low&0x3ff) + 0x10000) + pieces[i] = '' + return ''.join(pieces) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |