Mercurial > emacs
comparison test/cedet/tests/test.py @ 104494:e480034314ce
Add Semantic unit tests.
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Sun, 20 Sep 2009 04:00:13 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
104493:a4e1a12c8b97 | 104494:e480034314ce |
---|---|
1 # Test file for Python language. | |
2 # | |
3 # $Id: test.py,v 1.4 2007/03/08 02:16:33 zappo Exp $ | |
4 | |
5 # Simle class compount statement with blank lines sprinkled. | |
6 class Foo(Bar): | |
7 | |
8 x = 1 | |
9 | |
10 y = 2 | |
11 | |
12 # Simple def statement with no argument | |
13 def sss(): | |
14 i = 1 | |
15 | |
16 # Simple def statement with arguments | |
17 def ttt(x,y,z): | |
18 i = 1 | |
19 | |
20 import foo | |
21 | |
22 for x in y: | |
23 print x | |
24 | |
25 while y > 0: | |
26 y = y - 1 | |
27 | |
28 a=b=c=d=e=f=i=j=k=l=m=n=o=p=q=r=s=t=x=y=1 | |
29 | |
30 if x: | |
31 x = 2 | |
32 y = 3 | |
33 | |
34 x = 2 | |
35 y = 3 | |
36 s and t | |
37 q | r | |
38 o ^ p | |
39 m & n | |
40 k << l | |
41 z = 4 | |
42 i >> j | |
43 e / f | |
44 c * d | |
45 a + b | |
46 2 ** 5 | |
47 x | |
48 s = "a" "b" "c" | |
49 1 | |
50 | |
51 # implicit continuation lines, see | |
52 # http://docs.python.org/ref/implicit-joining.html | |
53 | |
54 a_list = [ 1, 2, 3, | |
55 4, 5, | |
56 6 ] | |
57 | |
58 a_tuple = (1, 2, 3, | |
59 | |
60 4, 5, 6) | |
61 | |
62 a_hash = { 'a':1, "b":2, | |
63 'c' : 3, | |
64 "d" : 4 } | |
65 | |
66 | |
67 def longarglist(a, | |
68 b, | |
69 c, | |
70 d): | |
71 a=1; | |
72 b=1; | |
73 c=1; | |
74 d=1; | |
75 | |
76 class longclasslist(xx.yyy, | |
77 zz.aa): | |
78 foo=1 | |
79 | |
80 | |
81 # wisent-python.wy chokes on this! -ryk 6/17/02 | |
82 | |
83 class HTTPServer(xxx.yyy): | |
84 allow_reuse_address = 1 # Seems to make sense in testing environment | |
85 def server_bind(self): | |
86 SocketServer.TCPServer.server_bind(self) | |
87 host, port = self.socket.getsockname() | |
88 self.server_name = socket.getfqdn(host) | |
89 self.server_port = port | |
90 | |
91 | |
92 ######################################################################### | |
93 ### /usr/lib/python2.2/BaseHTTPServer.py | |
94 ######################################################################### | |
95 | |
96 """HTTP server base class. | |
97 | |
98 Note: the class in this module doesn't implement any HTTP request; see | |
99 SimpleHTTPServer for simple implementations of GET, HEAD and POST | |
100 (including CGI scripts). | |
101 | |
102 Contents: | |
103 | |
104 - BaseHTTPRequestHandler: HTTP request handler base class | |
105 - test: test function | |
106 | |
107 XXX To do: | |
108 | |
109 - send server version | |
110 - log requests even later (to capture byte count) | |
111 - log user-agent header and other interesting goodies | |
112 - send error log to separate file | |
113 - are request names really case sensitive? | |
114 | |
115 """ | |
116 | |
117 | |
118 # See also: | |
119 # | |
120 # HTTP Working Group T. Berners-Lee | |
121 # INTERNET-DRAFT R. T. Fielding | |
122 # <draft-ietf-http-v10-spec-00.txt> H. Frystyk Nielsen | |
123 # Expires September 8, 1995 March 8, 1995 | |
124 # | |
125 # URL: http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt | |
126 | |
127 | |
128 # Log files | |
129 # --------- | |
130 # | |
131 # Here's a quote from the NCSA httpd docs about log file format. | |
132 # | |
133 # | The logfile format is as follows. Each line consists of: | |
134 # | | |
135 # | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb | |
136 # | | |
137 # | host: Either the DNS name or the IP number of the remote client | |
138 # | rfc931: Any information returned by identd for this person, | |
139 # | - otherwise. | |
140 # | authuser: If user sent a userid for authentication, the user name, | |
141 # | - otherwise. | |
142 # | DD: Day | |
143 # | Mon: Month (calendar name) | |
144 # | YYYY: Year | |
145 # | hh: hour (24-hour format, the machine's timezone) | |
146 # | mm: minutes | |
147 # | ss: seconds | |
148 # | request: The first line of the HTTP request as sent by the client. | |
149 # | ddd: the status code returned by the server, - if not available. | |
150 # | bbbb: the total number of bytes sent, | |
151 # | *not including the HTTP/1.0 header*, - if not available | |
152 # | | |
153 # | You can determine the name of the file accessed through request. | |
154 # | |
155 # (Actually, the latter is only true if you know the server configuration | |
156 # at the time the request was made!) | |
157 | |
158 | |
159 __version__ = "0.2" | |
160 | |
161 __all__ = ["HTTPServer", "BaseHTTPRequestHandler"] | |
162 | |
163 import sys | |
164 import time | |
165 import socket # For gethostbyaddr() | |
166 import mimetools | |
167 import SocketServer | |
168 | |
169 # Default error message | |
170 DEFAULT_ERROR_MESSAGE = """\ | |
171 <head> | |
172 <title>Error response</title> | |
173 </head> | |
174 <body> | |
175 <h1>Error response</h1> | |
176 <p>Error code %(code)d. | |
177 <p>Message: %(message)s. | |
178 <p>Error code explanation: %(code)s = %(explain)s. | |
179 </body> | |
180 """ | |
181 | |
182 | |
183 class HTTPServer(SocketServer.TCPServer): | |
184 | |
185 allow_reuse_address = 1 # Seems to make sense in testing environment | |
186 | |
187 def server_bind(self): | |
188 """Override server_bind to store the server name.""" | |
189 SocketServer.TCPServer.server_bind(self) | |
190 host, port = self.socket.getsockname() | |
191 self.server_name = socket.getfqdn(host) | |
192 self.server_port = port | |
193 | |
194 | |
195 class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler): | |
196 | |
197 """HTTP request handler base class. | |
198 | |
199 The following explanation of HTTP serves to guide you through the | |
200 code as well as to expose any misunderstandings I may have about | |
201 HTTP (so you don't need to read the code to figure out I'm wrong | |
202 :-). | |
203 | |
204 HTTP (HyperText Transfer Protocol) is an extensible protocol on | |
205 top of a reliable stream transport (e.g. TCP/IP). The protocol | |
206 recognizes three parts to a request: | |
207 | |
208 1. One line identifying the request type and path | |
209 2. An optional set of RFC-822-style headers | |
210 3. An optional data part | |
211 | |
212 The headers and data are separated by a blank line. | |
213 | |
214 The first line of the request has the form | |
215 | |
216 <command> <path> <version> | |
217 | |
218 where <command> is a (case-sensitive) keyword such as GET or POST, | |
219 <path> is a string containing path information for the request, | |
220 and <version> should be the string "HTTP/1.0". <path> is encoded | |
221 using the URL encoding scheme (using %xx to signify the ASCII | |
222 character with hex code xx). | |
223 | |
224 The protocol is vague about whether lines are separated by LF | |
225 characters or by CRLF pairs -- for compatibility with the widest | |
226 range of clients, both should be accepted. Similarly, whitespace | |
227 in the request line should be treated sensibly (allowing multiple | |
228 spaces between components and allowing trailing whitespace). | |
229 | |
230 Similarly, for output, lines ought to be separated by CRLF pairs | |
231 but most clients grok LF characters just fine. | |
232 | |
233 If the first line of the request has the form | |
234 | |
235 <command> <path> | |
236 | |
237 (i.e. <version> is left out) then this is assumed to be an HTTP | |
238 0.9 request; this form has no optional headers and data part and | |
239 the reply consists of just the data. | |
240 | |
241 The reply form of the HTTP 1.0 protocol again has three parts: | |
242 | |
243 1. One line giving the response code | |
244 2. An optional set of RFC-822-style headers | |
245 3. The data | |
246 | |
247 Again, the headers and data are separated by a blank line. | |
248 | |
249 The response code line has the form | |
250 | |
251 <version> <responsecode> <responsestring> | |
252 | |
253 where <version> is the protocol version (always "HTTP/1.0"), | |
254 <responsecode> is a 3-digit response code indicating success or | |
255 failure of the request, and <responsestring> is an optional | |
256 human-readable string explaining what the response code means. | |
257 | |
258 This server parses the request and the headers, and then calls a | |
259 function specific to the request type (<command>). Specifically, | |
260 a request SPAM will be handled by a method do_SPAM(). If no | |
261 such method exists the server sends an error response to the | |
262 client. If it exists, it is called with no arguments: | |
263 | |
264 do_SPAM() | |
265 | |
266 Note that the request name is case sensitive (i.e. SPAM and spam | |
267 are different requests). | |
268 | |
269 The various request details are stored in instance variables: | |
270 | |
271 - client_address is the client IP address in the form (host, | |
272 port); | |
273 | |
274 - command, path and version are the broken-down request line; | |
275 | |
276 - headers is an instance of mimetools.Message (or a derived | |
277 class) containing the header information; | |
278 | |
279 - rfile is a file object open for reading positioned at the | |
280 start of the optional input data part; | |
281 | |
282 - wfile is a file object open for writing. | |
283 | |
284 IT IS IMPORTANT TO ADHERE TO THE PROTOCOL FOR WRITING! | |
285 | |
286 The first thing to be written must be the response line. Then | |
287 follow 0 or more header lines, then a blank line, and then the | |
288 actual data (if any). The meaning of the header lines depends on | |
289 the command executed by the server; in most cases, when data is | |
290 returned, there should be at least one header line of the form | |
291 | |
292 Content-type: <type>/<subtype> | |
293 | |
294 where <type> and <subtype> should be registered MIME types, | |
295 e.g. "text/html" or "text/plain". | |
296 | |
297 """ | |
298 | |
299 # The Python system version, truncated to its first component. | |
300 sys_version = "Python/" + sys.version.split()[0] | |
301 | |
302 # The server software version. You may want to override this. | |
303 # The format is multiple whitespace-separated strings, | |
304 # where each string is of the form name[/version]. | |
305 server_version = "BaseHTTP/" + __version__ | |
306 | |
307 def parse_request(self): | |
308 """Parse a request (internal). | |
309 | |
310 The request should be stored in self.raw_request; the results | |
311 are in self.command, self.path, self.request_version and | |
312 self.headers. | |
313 | |
314 Return value is 1 for success, 0 for failure; on failure, an | |
315 error is sent back. | |
316 | |
317 """ | |
318 self.request_version = version = "HTTP/0.9" # Default | |
319 requestline = self.raw_requestline | |
320 if requestline[-2:] == '\r\n': | |
321 requestline = requestline[:-2] | |
322 elif requestline[-1:] == '\n': | |
323 requestline = requestline[:-1] | |
324 self.requestline = requestline | |
325 words = requestline.split() | |
326 if len(words) == 3: | |
327 [command, path, version] = words | |
328 if version[:5] != 'HTTP/': | |
329 self.send_error(400, "Bad request version (%s)" % `version`) | |
330 return 0 | |
331 elif len(words) == 2: | |
332 [command, path] = words | |
333 if command != 'GET': | |
334 self.send_error(400, | |
335 "Bad HTTP/0.9 request type (%s)" % `command`) | |
336 return 0 | |
337 else: | |
338 self.send_error(400, "Bad request syntax (%s)" % `requestline`) | |
339 return 0 | |
340 self.command, self.path, self.request_version = command, path, version | |
341 self.headers = self.MessageClass(self.rfile, 0) | |
342 return 1 | |
343 | |
344 def handle(self): | |
345 """Handle a single HTTP request. | |
346 | |
347 You normally don't need to override this method; see the class | |
348 __doc__ string for information on how to handle specific HTTP | |
349 commands such as GET and POST. | |
350 | |
351 """ | |
352 | |
353 self.raw_requestline = self.rfile.readline() | |
354 if not self.parse_request(): # An error code has been sent, just exit | |
355 return | |
356 mname = 'do_' + self.command | |
357 if not hasattr(self, mname): | |
358 self.send_error(501, "Unsupported method (%s)" % `self.command`) | |
359 return | |
360 method = getattr(self, mname) | |
361 method() | |
362 | |
363 def send_error(self, code, message=None): | |
364 """Send and log an error reply. | |
365 | |
366 Arguments are the error code, and a detailed message. | |
367 The detailed message defaults to the short entry matching the | |
368 response code. | |
369 | |
370 This sends an error response (so it must be called before any | |
371 output has been generated), logs the error, and finally sends | |
372 a piece of HTML explaining the error to the user. | |
373 | |
374 """ | |
375 | |
376 try: | |
377 short, long = self.responses[code] | |
378 except KeyError: | |
379 short, long = '???', '???' | |
380 if not message: | |
381 message = short | |
382 explain = long | |
383 self.log_error("code %d, message %s", code, message) | |
384 self.send_response(code, message) | |
385 self.send_header("Content-Type", "text/html") | |
386 self.end_headers() | |
387 self.wfile.write(self.error_message_format % | |
388 {'code': code, | |
389 'message': message, | |
390 'explain': explain}) | |
391 | |
392 error_message_format = DEFAULT_ERROR_MESSAGE | |
393 | |
394 def send_response(self, code, message=None): | |
395 """Send the response header and log the response code. | |
396 | |
397 Also send two standard headers with the server software | |
398 version and the current date. | |
399 | |
400 """ | |
401 self.log_request(code) | |
402 if message is None: | |
403 if self.responses.has_key(code): | |
404 message = self.responses[code][0] | |
405 else: | |
406 message = '' | |
407 if self.request_version != 'HTTP/0.9': | |
408 self.wfile.write("%s %s %s\r\n" % | |
409 (self.protocol_version, str(code), message)) | |
410 self.send_header('Server', self.version_string()) | |
411 self.send_header('Date', self.date_time_string()) | |
412 | |
413 def send_header(self, keyword, value): | |
414 """Send a MIME header.""" | |
415 if self.request_version != 'HTTP/0.9': | |
416 self.wfile.write("%s: %s\r\n" % (keyword, value)) | |
417 | |
418 def end_headers(self): | |
419 """Send the blank line ending the MIME headers.""" | |
420 if self.request_version != 'HTTP/0.9': | |
421 self.wfile.write("\r\n") | |
422 | |
423 def log_request(self, code='-', size='-'): | |
424 """Log an accepted request. | |
425 | |
426 This is called by send_reponse(). | |
427 | |
428 """ | |
429 | |
430 self.log_message('"%s" %s %s', | |
431 self.requestline, str(code), str(size)) | |
432 | |
433 def log_error(self, *args): | |
434 """Log an error. | |
435 | |
436 This is called when a request cannot be fulfilled. By | |
437 default it passes the message on to log_message(). | |
438 | |
439 Arguments are the same as for log_message(). | |
440 | |
441 XXX This should go to the separate error log. | |
442 | |
443 """ | |
444 | |
445 apply(self.log_message, args) | |
446 | |
447 def log_message(self, format, *args): | |
448 """Log an arbitrary message. | |
449 | |
450 This is used by all other logging functions. Override | |
451 it if you have specific logging wishes. | |
452 | |
453 The first argument, FORMAT, is a format string for the | |
454 message to be logged. If the format string contains | |
455 any % escapes requiring parameters, they should be | |
456 specified as subsequent arguments (it's just like | |
457 printf!). | |
458 | |
459 The client host and current date/time are prefixed to | |
460 every message. | |
461 | |
462 """ | |
463 | |
464 sys.stderr.write("%s - - [%s] %s\n" % | |
465 (self.address_string(), | |
466 self.log_date_time_string(), | |
467 format%args)) | |
468 | |
469 def version_string(self): | |
470 """Return the server software version string.""" | |
471 return self.server_version + ' ' + self.sys_version | |
472 | |
473 def date_time_string(self): | |
474 """Return the current date and time formatted for a message header.""" | |
475 now = time.time() | |
476 year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now) | |
477 s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( | |
478 self.weekdayname[wd], | |
479 day, self.monthname[month], year, | |
480 hh, mm, ss) | |
481 return s | |
482 | |
483 def log_date_time_string(self): | |
484 """Return the current time formatted for logging.""" | |
485 now = time.time() | |
486 year, month, day, hh, mm, ss, x, y, z = time.localtime(now) | |
487 s = "%02d/%3s/%04d %02d:%02d:%02d" % ( | |
488 day, self.monthname[month], year, hh, mm, ss) | |
489 return s | |
490 | |
491 weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] | |
492 | |
493 monthname = [None, | |
494 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', | |
495 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] | |
496 | |
497 def address_string(self): | |
498 """Return the client address formatted for logging. | |
499 | |
500 This version looks up the full hostname using gethostbyaddr(), | |
501 and tries to find a name that contains at least one dot. | |
502 | |
503 """ | |
504 | |
505 host, port = self.client_address | |
506 return socket.getfqdn(host) | |
507 | |
508 # Essentially static class variables | |
509 | |
510 # The version of the HTTP protocol we support. | |
511 # Don't override unless you know what you're doing (hint: incoming | |
512 # requests are required to have exactly this version string). | |
513 protocol_version = "HTTP/1.0" | |
514 | |
515 # The Message-like class used to parse headers | |
516 MessageClass = mimetools.Message | |
517 | |
518 # Table mapping response codes to messages; entries have the | |
519 # form {code: (shortmessage, longmessage)}. | |
520 # See http://www.w3.org/hypertext/WWW/Protocols/HTTP/HTRESP.html | |
521 responses = { | |
522 200: ('OK', 'Request fulfilled, document follows'), | |
523 201: ('Created', 'Document created, URL follows'), | |
524 202: ('Accepted', | |
525 'Request accepted, processing continues off-line'), | |
526 203: ('Partial information', 'Request fulfilled from cache'), | |
527 204: ('No response', 'Request fulfilled, nothing follows'), | |
528 | |
529 301: ('Moved', 'Object moved permanently -- see URI list'), | |
530 302: ('Found', 'Object moved temporarily -- see URI list'), | |
531 303: ('Method', 'Object moved -- see Method and URL list'), | |
532 304: ('Not modified', | |
533 'Document has not changed singe given time'), | |
534 | |
535 400: ('Bad request', | |
536 'Bad request syntax or unsupported method'), | |
537 401: ('Unauthorized', | |
538 'No permission -- see authorization schemes'), | |
539 402: ('Payment required', | |
540 'No payment -- see charging schemes'), | |
541 403: ('Forbidden', | |
542 'Request forbidden -- authorization will not help'), | |
543 404: ('Not found', 'Nothing matches the given URI'), | |
544 | |
545 500: ('Internal error', 'Server got itself in trouble'), | |
546 501: ('Not implemented', | |
547 'Server does not support this operation'), | |
548 502: ('Service temporarily overloaded', | |
549 'The server cannot process the request due to a high load'), | |
550 503: ('Gateway timeout', | |
551 'The gateway server did not receive a timely response'), | |
552 | |
553 } | |
554 | |
555 | |
556 def test(HandlerClass = BaseHTTPRequestHandler, | |
557 ServerClass = HTTPServer): | |
558 """Test the HTTP request handler class. | |
559 | |
560 This runs an HTTP server on port 8000 (or the first command line | |
561 argument). | |
562 | |
563 """ | |
564 | |
565 if sys.argv[1:]: | |
566 port = int(sys.argv[1]) | |
567 else: | |
568 port = 8000 | |
569 server_address = ('', port) | |
570 | |
571 httpd = ServerClass(server_address, HandlerClass) | |
572 | |
573 sa = httpd.socket.getsockname() | |
574 print "Serving HTTP on", sa[0], "port", sa[1], "..." | |
575 httpd.serve_forever() | |
576 | |
577 | |
578 if __name__ == '__main__': | |
579 test() |