Home | History | Annotate | Download | only in test
      1 from DocXMLRPCServer import DocXMLRPCServer
      2 import httplib
      3 import sys
      4 from test import test_support
      5 threading = test_support.import_module('threading')
      6 import unittest
      7 
      8 def make_request_and_skipIf(condition, reason):
      9     # If we skip the test, we have to make a request because
     10     # the server created in setUp blocks expecting one to come in.
     11     if not condition:
     12         return lambda func: func
     13     def decorator(func):
     14         def make_request_and_skip(self):
     15             self.client.request("GET", "/")
     16             self.client.getresponse()
     17             raise unittest.SkipTest(reason)
     18         return make_request_and_skip
     19     return decorator
     20 
     21 
     22 def make_server():
     23     serv = DocXMLRPCServer(("localhost", 0), logRequests=False)
     24 
     25     try:
     26         # Add some documentation
     27         serv.set_server_title("DocXMLRPCServer Test Documentation")
     28         serv.set_server_name("DocXMLRPCServer Test Docs")
     29         serv.set_server_documentation(
     30             "This is an XML-RPC server's documentation, but the server "
     31             "can be used by POSTing to /RPC2. Try self.add, too.")
     32 
     33         # Create and register classes and functions
     34         class TestClass(object):
     35             def test_method(self, arg):
     36                 """Test method's docs. This method truly does very little."""
     37                 self.arg = arg
     38 
     39         serv.register_introspection_functions()
     40         serv.register_instance(TestClass())
     41 
     42         def add(x, y):
     43             """Add two instances together. This follows PEP008, but has nothing
     44             to do with RFC1952. Case should matter: pEp008 and rFC1952.  Things
     45             that start with http and ftp should be auto-linked, too:
     46             http://google.com.
     47             """
     48             return x + y
     49 
     50         serv.register_function(add)
     51         serv.register_function(lambda x, y: x-y)
     52         return serv
     53     except:
     54         serv.server_close()
     55         raise
     56 
     57 class DocXMLRPCHTTPGETServer(unittest.TestCase):
     58     def setUp(self):
     59         # Enable server feedback
     60         DocXMLRPCServer._send_traceback_header = True
     61 
     62         self.serv = make_server()
     63         self.thread = threading.Thread(target=self.serv.serve_forever)
     64         self.thread.start()
     65 
     66         PORT = self.serv.server_address[1]
     67         self.client = httplib.HTTPConnection("localhost:%d" % PORT)
     68 
     69     def tearDown(self):
     70         self.client.close()
     71 
     72         # Disable server feedback
     73         DocXMLRPCServer._send_traceback_header = False
     74         self.serv.shutdown()
     75         self.thread.join()
     76         self.serv.server_close()
     77 
     78     def test_valid_get_response(self):
     79         self.client.request("GET", "/")
     80         response = self.client.getresponse()
     81 
     82         self.assertEqual(response.status, 200)
     83         self.assertEqual(response.getheader("Content-type"), "text/html")
     84 
     85         # Server raises an exception if we don't start to read the data
     86         response.read()
     87 
     88     def test_invalid_get_response(self):
     89         self.client.request("GET", "/spam")
     90         response = self.client.getresponse()
     91 
     92         self.assertEqual(response.status, 404)
     93         self.assertEqual(response.getheader("Content-type"), "text/plain")
     94 
     95         response.read()
     96 
     97     def test_lambda(self):
     98         """Test that lambda functionality stays the same.  The output produced
     99         currently is, I suspect invalid because of the unencoded brackets in the
    100         HTML, "<lambda>".
    101 
    102         The subtraction lambda method is tested.
    103         """
    104         self.client.request("GET", "/")
    105         response = self.client.getresponse()
    106 
    107         self.assertIn('<dl><dt><a name="-&lt;lambda&gt;"><strong>'
    108                       '&lt;lambda&gt;</strong></a>(x, y)</dt></dl>',
    109                       response.read())
    110 
    111     @make_request_and_skipIf(sys.flags.optimize >= 2,
    112                      "Docstrings are omitted with -O2 and above")
    113     def test_autolinking(self):
    114         """Test that the server correctly automatically wraps references to
    115         PEPS and RFCs with links, and that it linkifies text starting with
    116         http or ftp protocol prefixes.
    117 
    118         The documentation for the "add" method contains the test material.
    119         """
    120         self.client.request("GET", "/")
    121         response = self.client.getresponse()
    122 
    123         self.assertIn(
    124             ('<dl><dt><a name="-add"><strong>add</strong></a>(x, y)</dt><dd>'
    125              '<tt>Add&nbsp;two&nbsp;instances&nbsp;together.&nbsp;This&nbsp;'
    126              'follows&nbsp;<a href="http://www.python.org/dev/peps/pep-0008/">'
    127              'PEP008</a>,&nbsp;but&nbsp;has&nbsp;nothing<br>\nto&nbsp;do&nbsp;'
    128              'with&nbsp;<a href="http://www.rfc-editor.org/rfc/rfc1952.txt">'
    129              'RFC1952</a>.&nbsp;Case&nbsp;should&nbsp;matter:&nbsp;pEp008&nbsp;'
    130              'and&nbsp;rFC1952.&nbsp;&nbsp;Things<br>\nthat&nbsp;start&nbsp;'
    131              'with&nbsp;http&nbsp;and&nbsp;ftp&nbsp;should&nbsp;be&nbsp;'
    132              'auto-linked,&nbsp;too:<br>\n<a href="http://google.com">'
    133              'http://google.com</a>.</tt></dd></dl>'), response.read())
    134 
    135     @make_request_and_skipIf(sys.flags.optimize >= 2,
    136                      "Docstrings are omitted with -O2 and above")
    137     def test_system_methods(self):
    138         """Test the presence of three consecutive system.* methods.
    139 
    140         This also tests their use of parameter type recognition and the
    141         systems related to that process.
    142         """
    143         self.client.request("GET", "/")
    144         response = self.client.getresponse()
    145 
    146         self.assertIn(
    147             ('<dl><dt><a name="-system.listMethods"><strong>system.listMethods'
    148              '</strong></a>()</dt><dd><tt><a href="#-system.listMethods">system'
    149              '.listMethods</a>()&nbsp;=&gt;&nbsp;[\'add\',&nbsp;\'subtract\','
    150              '&nbsp;\'multiple\']<br>\n&nbsp;<br>\nReturns&nbsp;a&nbsp;list'
    151              '&nbsp;of&nbsp;the&nbsp;methods&nbsp;supported&nbsp;by&nbsp;the'
    152              '&nbsp;server.</tt></dd></dl>\n <dl><dt><a name="-system.methodHelp">'
    153              '<strong>system.methodHelp</strong></a>(method_name)</dt><dd><tt>'
    154              '<a href="#-system.methodHelp">system.methodHelp</a>(\'add\')&nbsp;'
    155              '=&gt;&nbsp;"Adds&nbsp;two&nbsp;integers&nbsp;together"<br>\n&nbsp;'
    156              '<br>\nReturns&nbsp;a&nbsp;string&nbsp;containing&nbsp;documentation'
    157              '&nbsp;for&nbsp;the&nbsp;specified&nbsp;method.</tt></dd></dl>\n '
    158              '<dl><dt><a name="-system.methodSignature"><strong>system.'
    159              'methodSignature</strong></a>(method_name)</dt><dd><tt><a href="#-'
    160              'system.methodSignature">system.methodSignature</a>(\'add\')&nbsp;'
    161              '=&gt;&nbsp;[double,&nbsp;int,&nbsp;int]<br>\n&nbsp;<br>\nReturns'
    162              '&nbsp;a&nbsp;list&nbsp;describing&nbsp;the&nbsp;signature&nbsp;of'
    163              '&nbsp;the&nbsp;method.&nbsp;In&nbsp;the<br>\nabove&nbsp;example,'
    164              '&nbsp;the&nbsp;add&nbsp;method&nbsp;takes&nbsp;two&nbsp;integers'
    165              '&nbsp;as&nbsp;arguments<br>\nand&nbsp;returns&nbsp;a&nbsp;double'
    166              '&nbsp;result.<br>\n&nbsp;<br>\nThis&nbsp;server&nbsp;does&nbsp;'
    167              'NOT&nbsp;support&nbsp;system.methodSignature.</tt></dd></dl>'),
    168             response.read())
    169 
    170     def test_autolink_dotted_methods(self):
    171         """Test that selfdot values are made strong automatically in the
    172         documentation."""
    173         self.client.request("GET", "/")
    174         response = self.client.getresponse()
    175 
    176         self.assertIn("""Try&nbsp;self.<strong>add</strong>,&nbsp;too.""",
    177                       response.read())
    178 
    179 def test_main():
    180     test_support.run_unittest(DocXMLRPCHTTPGETServer)
    181 
    182 if __name__ == '__main__':
    183     test_main()
    184