summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorChristian Heimes <christian@cheimes.de>2007-12-10 16:18:49 (GMT)
committerChristian Heimes <christian@cheimes.de>2007-12-10 16:18:49 (GMT)
commit2f1019e7521b13fb127f53444b3ebe7116d12037 (patch)
tree9aac86f3054fb754b0e7ae54afdfcaba1c46ecb9 /Lib
parent0ded5b54bb499865fb4ab8c0ac3d0977df9a334d (diff)
downloadcpython-2f1019e7521b13fb127f53444b3ebe7116d12037.zip
cpython-2f1019e7521b13fb127f53444b3ebe7116d12037.tar.gz
cpython-2f1019e7521b13fb127f53444b3ebe7116d12037.tar.bz2
Merged revisions 59441-59449 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r59442 | georg.brandl | 2007-12-09 22:15:07 +0100 (Sun, 09 Dec 2007) | 5 lines Two fixes in DocXMLRPCServer: * remove parameter default that didn't make sense * properly escape values in output Thanks to Jeff Wheeler from GHOP! ........ r59444 | georg.brandl | 2007-12-09 23:38:26 +0100 (Sun, 09 Dec 2007) | 2 lines Add Jeff Wheeler. ........ r59445 | georg.brandl | 2007-12-09 23:39:12 +0100 (Sun, 09 Dec 2007) | 2 lines Add DocXMLRPCServer test from GHOP task #136, written by Jeff Wheeler. ........ r59447 | christian.heimes | 2007-12-10 16:12:41 +0100 (Mon, 10 Dec 2007) | 1 line Added wide char api variants of getch and putch to msvcrt module. The wide char methods are required to fix #1578 in py3k. I figured out that they might be useful in 2.6, too. ........ r59448 | christian.heimes | 2007-12-10 16:39:09 +0100 (Mon, 10 Dec 2007) | 1 line Stupid save all didn't safe it all ... ........
Diffstat (limited to 'Lib')
-rw-r--r--Lib/DocXMLRPCServer.py32
-rw-r--r--Lib/test/test_docxmlrpc.py152
2 files changed, 156 insertions, 28 deletions
diff --git a/Lib/DocXMLRPCServer.py b/Lib/DocXMLRPCServer.py
index 08e1f10..c95210a 100644
--- a/Lib/DocXMLRPCServer.py
+++ b/Lib/DocXMLRPCServer.py
@@ -64,14 +64,15 @@ class ServerHTMLDoc(pydoc.HTMLDoc):
results.append(escape(text[here:]))
return ''.join(results)
- def docroutine(self, object, name=None, mod=None,
+ def docroutine(self, object, name, mod=None,
funcs={}, classes={}, methods={}, cl=None):
"""Produce HTML documentation for a function or method object."""
anchor = (cl and cl.__name__ or '') + '-' + name
note = ''
- title = '<a name="%s"><strong>%s</strong></a>' % (anchor, name)
+ title = '<a name="%s"><strong>%s</strong></a>' % (
+ self.escape(anchor), self.escape(name))
if inspect.ismethod(object):
args, varargs, varkw, defaults = inspect.getargspec(object)
@@ -113,6 +114,7 @@ class ServerHTMLDoc(pydoc.HTMLDoc):
fdict[key] = '#-' + key
fdict[value] = fdict[key]
+ server_name = self.escape(server_name)
head = '<big><big><strong>%s</strong></big></big>' % server_name
result = self.heading(head, '#ffffff', '#7799ee')
@@ -280,29 +282,3 @@ class DocCGIXMLRPCRequestHandler( CGIXMLRPCRequestHandler,
def __init__(self):
CGIXMLRPCRequestHandler.__init__(self)
XMLRPCDocGenerator.__init__(self)
-
-if __name__ == '__main__':
- def deg_to_rad(deg):
- """deg_to_rad(90) => 1.5707963267948966
-
- Converts an angle in degrees to an angle in radians"""
- import math
- return deg * math.pi / 180
-
- server = DocXMLRPCServer(("localhost", 8000))
-
- server.set_server_title("Math Server")
- server.set_server_name("Math XML-RPC Server")
- server.set_server_documentation("""This server supports various mathematical functions.
-
-You can use it from Python as follows:
-
->>> from xmlrpclib import ServerProxy
->>> s = ServerProxy("http://localhost:8000")
->>> s.deg_to_rad(90.0)
-1.5707963267948966""")
-
- server.register_function(deg_to_rad)
- server.register_introspection_functions()
-
- server.serve_forever()
diff --git a/Lib/test/test_docxmlrpc.py b/Lib/test/test_docxmlrpc.py
new file mode 100644
index 0000000..55c2143
--- /dev/null
+++ b/Lib/test/test_docxmlrpc.py
@@ -0,0 +1,152 @@
+from DocXMLRPCServer import DocXMLRPCServer
+import httplib
+from test import test_support
+import threading
+import time
+import unittest
+import xmlrpclib
+
+PORT = None
+
+def server(evt, numrequests):
+ try:
+ serv = DocXMLRPCServer(("localhost", 0), logRequests=False)
+
+ global PORT
+ PORT = serv.socket.getsockname()[1]
+
+ # Add some documentation
+ serv.set_server_title("DocXMLRPCServer Test Documentation")
+ serv.set_server_name("DocXMLRPCServer Test Docs")
+ serv.set_server_documentation(
+"""This is an XML-RPC server's documentation, but the server can be used by
+POSTing to /RPC2. Try self.add, too.""")
+
+ # Create and register classes and functions
+ class TestClass(object):
+ def test_method(self, arg):
+ """Test method's docs. This method truly does very little."""
+ self.arg = arg
+
+ serv.register_introspection_functions()
+ serv.register_instance(TestClass())
+
+ def add(x, y):
+ """Add two instances together. This follows PEP008, but has nothing
+ to do with RFC1952. Case should matter: pEp008 and rFC1952. Things
+ that start with http and ftp should be auto-linked, too:
+ http://google.com.
+ """
+ return x + y
+
+ serv.register_function(add)
+ serv.register_function(lambda x, y: x-y)
+
+ while numrequests > 0:
+ serv.handle_request()
+ numrequests -= 1
+ except socket.timeout:
+ pass
+ finally:
+ serv.server_close()
+ PORT = None
+ evt.set()
+
+class DocXMLRPCHTTPGETServer(unittest.TestCase):
+ def setUp(self):
+ # Enable server feedback
+ DocXMLRPCServer._send_traceback_header = True
+
+ self.evt = threading.Event()
+ threading.Thread(target=server, args=(self.evt, 1)).start()
+
+ # wait for port to be assigned
+ n = 1000
+ while n > 0 and PORT is None:
+ time.sleep(0.001)
+ n -= 1
+
+ self.client = httplib.HTTPConnection("localhost:%d" % PORT)
+
+ def tearDown(self):
+ self.client.close()
+
+ self.evt.wait()
+
+ # Disable server feedback
+ DocXMLRPCServer._send_traceback_header = False
+
+ def test_valid_get_response(self):
+ self.client.request("GET", "/")
+ response = self.client.getresponse()
+
+ self.assertEqual(response.status, 200)
+ self.assertEqual(response.getheader("Content-type"), "text/html")
+
+ # Server throws an exception if we don't start to read the data
+ response.read()
+
+ def test_invalid_get_response(self):
+ self.client.request("GET", "/spam")
+ response = self.client.getresponse()
+
+ self.assertEqual(response.status, 404)
+ self.assertEqual(response.getheader("Content-type"), "text/plain")
+
+ response.read()
+
+ def test_lambda(self):
+ """Test that lambda functionality stays the same. The output produced
+ currently is, I suspect invalid because of the unencoded brackets in the
+ HTML, "<lambda>".
+
+ The subtraction lambda method is tested.
+ """
+ self.client.request("GET", "/")
+ response = self.client.getresponse()
+
+ self.assert_(
+"""<dl><dt><a name="-&lt;lambda&gt;"><strong>&lt;lambda&gt;</strong></a>(x, y)</dt></dl>"""
+ in response.read())
+
+ def test_autolinking(self):
+ """Test that the server correctly automatically wraps references to PEPS
+ and RFCs with links, and that it linkifies text starting with http or
+ ftp protocol prefixes.
+
+ The documentation for the "add" method contains the test material.
+ """
+ self.client.request("GET", "/")
+ response = self.client.getresponse()
+
+ self.assert_( # This is ugly ... how can it be made better?
+"""<dl><dt><a name="-add"><strong>add</strong></a>(x, y)</dt><dd><tt>Add&nbsp;two&nbsp;instances&nbsp;together.&nbsp;This&nbsp;follows&nbsp;<a href="http://www.python.org/peps/pep-0008.html">PEP008</a>,&nbsp;but&nbsp;has&nbsp;nothing<br>\nto&nbsp;do&nbsp;with&nbsp;<a href="http://www.rfc-editor.org/rfc/rfc1952.txt">RFC1952</a>.&nbsp;Case&nbsp;should&nbsp;matter:&nbsp;pEp008&nbsp;and&nbsp;rFC1952.&nbsp;&nbsp;Things<br>\nthat&nbsp;start&nbsp;with&nbsp;http&nbsp;and&nbsp;ftp&nbsp;should&nbsp;be&nbsp;auto-linked,&nbsp;too:<br>\n<a href="http://google.com">http://google.com</a>.</tt></dd></dl>"""
+ in response.read())
+
+ def test_system_methods(self):
+ """Test the precense of three consecutive system.* methods.
+
+ This also tests their use of parameter type recognition and the systems
+ related to that process.
+ """
+ self.client.request("GET", "/")
+ response = self.client.getresponse()
+
+ self.assert_(
+"""<dl><dt><a name="-system.listMethods"><strong>system.listMethods</strong></a>()</dt><dd><tt><a href="#-system.listMethods">system.listMethods</a>()&nbsp;=&gt;&nbsp;[\'add\',&nbsp;\'subtract\',&nbsp;\'multiple\']<br>\n&nbsp;<br>\nReturns&nbsp;a&nbsp;list&nbsp;of&nbsp;the&nbsp;methods&nbsp;supported&nbsp;by&nbsp;the&nbsp;server.</tt></dd></dl>\n <dl><dt><a name="-system.methodHelp"><strong>system.methodHelp</strong></a>(method_name)</dt><dd><tt><a href="#-system.methodHelp">system.methodHelp</a>(\'add\')&nbsp;=&gt;&nbsp;"Adds&nbsp;two&nbsp;integers&nbsp;together"<br>\n&nbsp;<br>\nReturns&nbsp;a&nbsp;string&nbsp;containing&nbsp;documentation&nbsp;for&nbsp;the&nbsp;specified&nbsp;method.</tt></dd></dl>\n <dl><dt><a name="-system.methodSignature"><strong>system.methodSignature</strong></a>(method_name)</dt><dd><tt><a href="#-system.methodSignature">system.methodSignature</a>(\'add\')&nbsp;=&gt;&nbsp;[double,&nbsp;int,&nbsp;int]<br>\n&nbsp;<br>\nReturns&nbsp;a&nbsp;list&nbsp;describing&nbsp;the&nbsp;signature&nbsp;of&nbsp;the&nbsp;method.&nbsp;In&nbsp;the<br>\nabove&nbsp;example,&nbsp;the&nbsp;add&nbsp;method&nbsp;takes&nbsp;two&nbsp;integers&nbsp;as&nbsp;arguments<br>\nand&nbsp;returns&nbsp;a&nbsp;double&nbsp;result.<br>\n&nbsp;<br>\nThis&nbsp;server&nbsp;does&nbsp;NOT&nbsp;support&nbsp;system.methodSignature.</tt></dd></dl>"""
+ in response.read())
+
+ def test_autolink_dotted_methods(self):
+ """Test that selfdot values are made strong automatically in the
+ documentation."""
+ self.client.request("GET", "/")
+ response = self.client.getresponse()
+
+ self.assert_("""Try&nbsp;self.<strong>add</strong>,&nbsp;too.""" in
+ response.read())
+
+def test_main():
+ test_support.run_unittest(DocXMLRPCHTTPGETServer)
+
+if __name__ == '__main__':
+ test_main()