import sys import difflib import subprocess import re import pydoc import unittest import test.test_support from test import pydoc_mod expected_text_pattern = \ """ NAME test.pydoc_mod - This is a test module for test_pydoc FILE %s CLASSES __builtin__.object B A \x20\x20\x20\x20 class A | Hello and goodbye |\x20\x20 | Methods defined here: |\x20\x20 | __init__() | Wow, I have no function! \x20\x20\x20\x20 class B(__builtin__.object) | Data descriptors defined here: |\x20\x20 | __dict__ | dictionary for instance variables (if defined) |\x20\x20 | __weakref__ | list of weak references to the object (if defined) |\x20\x20 | ---------------------------------------------------------------------- | Data and other attributes defined here: |\x20\x20 | NO_MEANING = 'eggs' FUNCTIONS doc_func() This function solves all of the world's problems: hunger lack of Python war \x20\x20\x20\x20 nodoc_func() DATA __author__ = 'Benjamin Peterson' __credits__ = 'Nobody' __package__ = None __version__ = '1.2.3.4' VERSION 1.2.3.4 AUTHOR Benjamin Peterson CREDITS Nobody """.strip() expected_html_pattern = \ """
 
 
test.pydoc_mod (version 1.2.3.4)
index
%s

This is a test module for test_pydoc

\x20\x20\x20\x20
 
Classes
       
__builtin__.object
B
A

\x20\x20\x20\x20
 
class A
    Hello and goodbye
 
  Methods defined here:
__init__()
Wow, I have no function!

\x20\x20\x20\x20
 
class B(__builtin__.object)
     Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

Data and other attributes defined here:
NO_MEANING = 'eggs'

\x20\x20\x20\x20
 
Functions
       
doc_func()
This function solves all of the world's problems:
hunger
lack of Python
war
nodoc_func()

\x20\x20\x20\x20
 
Data
        __author__ = 'Benjamin Peterson'
__credits__ = 'Nobody'
__package__ = None
__version__ = '1.2.3.4'

\x20\x20\x20\x20
 
Author
        Benjamin Peterson

\x20\x20\x20\x20
 
Credits
        Nobody
""".strip() # output pattern for missing module missing_pattern = "no Python documentation found for '%s'" def run_pydoc(module_name, *args): """ Runs pydoc on the specified module. Returns the stripped output of pydoc. """ cmd = [sys.executable, pydoc.__file__, " ".join(args), module_name] output = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout.read() return output.strip() def get_pydoc_html(module): "Returns pydoc generated output as html" output = pydoc.HTMLDoc().docmodule(module) return output.strip() def get_pydoc_text(module): "Returns pydoc generated output as text" output = pydoc.TextDoc().docmodule(module) # cleanup the extra text formatting that pydoc preforms patt = re.compile('\b.') output = patt.sub('', output) return output.strip() def print_diffs(text1, text2): "Prints unified diffs for two texts" lines1 = text1.splitlines() lines2 = text2.splitlines() diffs = difflib.unified_diff(lines1, lines2, n=0) diffs = list(diffs) # its a generator print '\n'.join(diffs) def get_mod_file(module): """Returns the name of the .py file if the module is compiled""" mod_file = module.__file__ return mod_file if mod_file.endswith("py") else mod_file[:-3] + "py" class PyDocDocTest(unittest.TestCase): def test_html_doc(self): result = get_pydoc_html(pydoc_mod) mod_file = get_mod_file(pydoc_mod) expected_html = expected_html_pattern % (mod_file, mod_file) if result != expected_html: print_diffs(result, expected_html) self.fail("outputs are not equal, see diff above") def test_text_doc(self): result = get_pydoc_text(pydoc_mod) expected_text = expected_text_pattern % get_mod_file(pydoc_mod) if result != expected_text: print_diffs(result, expected_text) self.fail("outputs are not equal, see diff above") def test_not_here(self): missing_module = "test.i_am_not_here" result = run_pydoc(missing_module) expected = missing_pattern % missing_module self.assertEqual(expected, result, "documentation for missing module found") class TestDescriptions(unittest.TestCase): def test_module(self): # Check that pydocfodder module can be described from test import pydocfodder doc = pydoc.render_doc(pydocfodder) self.assert_("pydocfodder" in doc) def test_classic_class(self): class C: "Classic class" c = C() self.assertEqual(pydoc.describe(C), 'class C') self.assertEqual(pydoc.describe(c), 'instance of C') self.assert_('instance of C in module test.test_pydoc' in pydoc.render_doc(c)) def test_class(self): class C(object): "New-style class" c = C() self.assertEqual(pydoc.describe(C), 'class C') self.assertEqual(pydoc.describe(c), 'C') self.assert_('C in module test.test_pydoc object' in pydoc.render_doc(c)) def test_main(): test.test_support.run_unittest(PyDocDocTest, TestDescriptions) if __name__ == "__main__": test_main()