From d5f204fc3738733a27c4796d0108c1455597d69f Mon Sep 17 00:00:00 2001 From: Ian Bicking Date: Mon, 22 Aug 2005 22:56:15 +0000 Subject: Removed and moved last of paste.tests --- paste/doctest_webapp.py | 439 ++++++++++++++++++++++++++++++++++++++++++ paste/tests/__init__.py | 1 - paste/tests/doctest_webapp.py | 439 ------------------------------------------ paste/tests/echotest.py | 109 ----------- 4 files changed, 439 insertions(+), 549 deletions(-) create mode 100755 paste/doctest_webapp.py delete mode 100644 paste/tests/__init__.py delete mode 100755 paste/tests/doctest_webapp.py delete mode 100755 paste/tests/echotest.py diff --git a/paste/doctest_webapp.py b/paste/doctest_webapp.py new file mode 100755 index 0000000..a8a63c9 --- /dev/null +++ b/paste/doctest_webapp.py @@ -0,0 +1,439 @@ +#!/usr/bin/env python2.4 +""" +These are functions for use when doctest-testing a document. +""" + +import subprocess +import doctest +import os +import sys +import shutil +import re +import cgi +import rfc822 +from cStringIO import StringIO +from paste import server +from paste import wsgilib +import PySourceColor + + +here = os.path.abspath(__file__) +paste_parent = os.path.dirname( + os.path.dirname(os.path.dirname(here))) + +def run(command): + data = run_raw(command) + if data: + print data + +def run_raw(command): + """ + Runs the string command, returns any output. + """ + proc = subprocess.Popen(command, shell=True, + stderr=subprocess.STDOUT, + stdout=subprocess.PIPE, env=_make_env()) + data = proc.stdout.read() + proc.wait() + while data.endswith('\n') or data.endswith('\r'): + data = data[:-1] + if data: + data = '\n'.join( + [l for l in data.splitlines() if l]) + return data + else: + return '' + +def run_command(command, name, and_print=False): + output = run_raw(command) + data = '$ %s\n%s' % (command, output) + show_file('shell-command', name, description='shell transcript', + data=data) + if and_print and output: + print output + +def _make_env(): + env = os.environ.copy() + env['PATH'] = (env.get('PATH', '') + + ':' + + os.path.join(paste_parent, 'scripts') + + ':' + + os.path.join(paste_parent, 'paste', '3rd-party', + 'sqlobject-files', 'scripts')) + env['PYTHONPATH'] = (env.get('PYTHONPATH', '') + + ':' + + paste_parent) + return env + +def clear_dir(dir): + """ + Clears (deletes) the given directory + """ + shutil.rmtree(dir, True) + +def ls(dir=None, recurse=False, indent=0): + """ + Show a directory listing + """ + dir = dir or os.getcwd() + fns = os.listdir(dir) + fns.sort() + for fn in fns: + full = os.path.join(dir, fn) + if os.path.isdir(full): + fn = fn + '/' + print ' '*indent + fn + if os.path.isdir(full) and recurse: + ls(dir=full, recurse=True, indent=indent+2) + +def make_app(dir): + os.chdir(dir) + sys.path.append(os.path.dirname(dir)) + conf, app = server.load_commandline((), allow_reload=False) + assert conf is not None, ( + "server.load_commandline requested exit with code %r" + % app) + return app + +default_app = None +default_url = None + +def set_default_app(app, url): + global default_app + global default_url + default_app = app + default_url = url + +def resource_filename(fn): + """ + Returns the filename of the resource -- generally in the directory + resources/DocumentName/fn + """ + return os.path.join( + os.path.dirname(sys.testing_document_filename), + 'resources', + os.path.splitext(os.path.basename(sys.testing_document_filename))[0], + fn) + +def show(path_info, example_name): + fn = resource_filename(example_name + '.html') + out = StringIO() + assert default_app is not None, ( + "No default_app set") + url = default_url + path_info + out.write('%s
\n' + % (url, url)) + out.write('
\n') + proc = subprocess.Popen( + ['paster', 'serve' '--server=console', '--no-verbose', + '--url=' + path_info], + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + env=_make_env()) + stdout, errors = proc.communicate() + stdout = StringIO(stdout) + headers = rfc822.Message(stdout) + content = stdout.read() + for header, value in headers.items(): + if header.lower() == 'status' and int(value.split()[0]) == 200: + continue + if header.lower() in ('content-type', 'content-length'): + continue + if (header.lower() == 'set-cookie' + and value.startswith('_SID_')): + continue + out.write('%s: %s
\n' + % (header, value)) + lines = [l for l in content.splitlines() if l.strip()] + for line in lines: + out.write(line + '\n') + if errors: + out.write('
%s
' + % errors) + out.write('
\n') + result = out.getvalue() + if not os.path.exists(fn): + f = open(fn, 'wb') + f.write(result) + f.close() + else: + f = open(fn, 'rb') + expected = f.read() + f.close() + if not html_matches(expected, result): + print 'Pages did not match. Expected from %s:' % fn + print '-'*60 + print expected + print '='*60 + print 'Actual output:' + print '-'*60 + print result + +def html_matches(pattern, text): + return True + regex = re.escape(pattern) + regex = regex.replace(r'\.\.\.', '.*') + regex = re.sub(r'0x[0-9a-f]+', '.*', regex) + regex = '^%s$' % regex + return re.search(regex, text) + +def convert_docstring_string(data): + if data.startswith('\n'): + data = data[1:] + lines = data.splitlines() + new_lines = [] + for line in lines: + if line.rstrip() == '.': + new_lines.append('') + else: + new_lines.append(line) + data = '\n'.join(new_lines) + '\n' + return data + +def create_file(path, version, data): + data = convert_docstring_string(data) + write_data(path, data) + show_file(path, version) + +def append_to_file(path, version, data): + data = convert_docstring_string(data) + f = open(path, 'a') + f.write(data) + f.close() + # I think these appends can happen so quickly (in less than a second) + # that the .pyc file doesn't appear to be expired, even though it + # is after we've made this change; so we have to get rid of the .pyc + # file: + if path.endswith('.py'): + pyc_file = path + 'c' + if os.path.exists(pyc_file): + os.unlink(pyc_file) + show_file(path, version, description='added to %s' % path, + data=data) + +def show_file(path, version, description=None, data=None): + ext = os.path.splitext(path)[1] + if data is None: + f = open(path, 'rb') + data = f.read() + f.close() + if ext == '.py': + html = ('
%s
' + % PySourceColor.str2html(data, PySourceColor.dark)) + else: + html = '
%s
' % cgi.escape(data, 1) + html = '%s
%s' % ( + description or path, html) + write_data(resource_filename('%s.%s.gen.html' % (path, version)), + html) + +def call_source_highlight(input, format): + proc = subprocess.Popen(['source-highlight', '--out-format=html', + '--no-doc', '--css=none', + '--src-lang=%s' % format], shell=False, + stdout=subprocess.PIPE) + stdout, stderr = proc.communicate(input) + result = stdout + proc.wait() + return result + + +def write_data(path, data): + dir = os.path.dirname(os.path.abspath(path)) + if not os.path.exists(dir): + os.makedirs(dir) + f = open(path, 'wb') + f.write(data) + f.close() + + +def change_file(path, changes): + f = open(os.path.abspath(path), 'rb') + lines = f.readlines() + f.close() + for change_type, line, text in changes: + if change_type == 'insert': + lines[line:line] = [text] + elif change_type == 'delete': + lines[line:text] = [] + else: + assert 0, ( + "Unknown change_type: %r" % change_type) + f = open(path, 'wb') + f.write(''.join(lines)) + f.close() + +class LongFormDocTestParser(doctest.DocTestParser): + + """ + This parser recognizes some reST comments as commands, without + prompts or expected output, like: + + .. run: + + do_this(... + ...) + """ + + _EXAMPLE_RE = re.compile(r""" + # Source consists of a PS1 line followed by zero or more PS2 lines. + (?: (?P + (?:^(?P [ ]*) >>> .*) # PS1 line + (?:\n [ ]* \.\.\. .*)*) # PS2 lines + \n? + # Want consists of any non-blank lines that do not start with PS1. + (?P (?:(?![ ]*$) # Not a blank line + (?![ ]*>>>) # Not a line starting with PS1 + .*$\n? # But any other line + )*)) + | + (?: # This is for longer commands that are prefixed with a reST + # comment like '.. run:' (two colons makes that a directive). + # These commands cannot have any output. + + (?:^\.\.[ ]*(?Prun):[ ]*\n) # Leading command/command + (?:[ ]*\n)? # Blank line following + (?P + (?:(?P [ ]+)[^ ].*$) + (?:\n [ ]+ .*)*) + ) + | + (?: # This is for shell commands + + (?P + (?:^(P [ ]*) [$] .*) # Shell line + (?:\n [ ]* [>] .*)*) # Continuation + \n? + # Want consists of any non-blank lines that do not start with $ + (?P (?:(?![ ]*$) + (?![ ]*[$]$) + .*$\n? + )*)) + """, re.MULTILINE | re.VERBOSE) + + def _parse_example(self, m, name, lineno): + r""" + Given a regular expression match from `_EXAMPLE_RE` (`m`), + return a pair `(source, want)`, where `source` is the matched + example's source code (with prompts and indentation stripped); + and `want` is the example's expected output (with indentation + stripped). + + `name` is the string's name, and `lineno` is the line number + where the example starts; both are used for error messages. + + >>> def parseit(s): + ... p = LongFormDocTestParser() + ... return p._parse_example(p._EXAMPLE_RE.search(s), '', 1) + >>> parseit('>>> 1\n1') + ('1', {}, '1', None) + >>> parseit('>>> (1\n... +1)\n2') + ('(1\n+1)', {}, '2', None) + >>> parseit('.. run:\n\n test1\n test2\n') + ('test1\ntest2', {}, '', None) + """ + # Get the example's indentation level. + runner = m.group('run') or '' + indent = len(m.group('%sindent' % runner)) + + # Divide source into lines; check that they're properly + # indented; and then strip their indentation & prompts. + source_lines = m.group('%ssource' % runner).split('\n') + if runner: + self._check_prefix(source_lines[1:], ' '*indent, name, lineno) + else: + self._check_prompt_blank(source_lines, indent, name, lineno) + self._check_prefix(source_lines[2:], ' '*indent + '.', name, lineno) + if runner: + source = '\n'.join([sl[indent:] for sl in source_lines]) + else: + source = '\n'.join([sl[indent+4:] for sl in source_lines]) + + if runner: + want = '' + exc_msg = None + else: + # Divide want into lines; check that it's properly indented; and + # then strip the indentation. Spaces before the last newline should + # be preserved, so plain rstrip() isn't good enough. + want = m.group('want') + want_lines = want.split('\n') + if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]): + del want_lines[-1] # forget final newline & spaces after it + self._check_prefix(want_lines, ' '*indent, name, + lineno + len(source_lines)) + want = '\n'.join([wl[indent:] for wl in want_lines]) + + # If `want` contains a traceback message, then extract it. + m = self._EXCEPTION_RE.match(want) + if m: + exc_msg = m.group('msg') + else: + exc_msg = None + + # Extract options from the source. + options = self._find_options(source, name, lineno) + + return source, options, want, exc_msg + + + def parse(self, string, name=''): + """ + Divide the given string into examples and intervening text, + and return them as a list of alternating Examples and strings. + Line numbers for the Examples are 0-based. The optional + argument `name` is a name identifying this string, and is only + used for error messages. + """ + string = string.expandtabs() + # If all lines begin with the same indentation, then strip it. + min_indent = self._min_indent(string) + if min_indent > 0: + string = '\n'.join([l[min_indent:] for l in string.split('\n')]) + + output = [] + charno, lineno = 0, 0 + # Find all doctest examples in the string: + for m in self._EXAMPLE_RE.finditer(string): + # Add the pre-example text to `output`. + output.append(string[charno:m.start()]) + # Update lineno (lines before this example) + lineno += string.count('\n', charno, m.start()) + # Extract info from the regexp match. + (source, options, want, exc_msg) = \ + self._parse_example(m, name, lineno) + # Create an Example, and add it to the list. + if not self._IS_BLANK_OR_COMMENT(source): + # @@: Erg, this is the only line I need to change... + output.append( doctest.Example(source, want, exc_msg, + lineno=lineno, + indent=min_indent+len(m.group('indent') or m.group('runindent')), + options=options) ) + # Update lineno (lines inside this example) + lineno += string.count('\n', m.start(), m.end()) + # Update charno. + charno = m.end() + # Add any remaining post-example text to `output`. + output.append(string[charno:]) + return output + + + +if __name__ == '__main__': + import sys + if sys.argv[1:] and sys.argv[1] == 'doctest': + doctest.testmod() + sys.exit() + if not paste_parent in sys.path: + sys.path.append(paste_parent) + for fn in sys.argv[1:]: + fn = os.path.abspath(fn) + # @@: OK, ick; but this module gets loaded twice + sys.testing_document_filename = fn + doctest.testfile( + fn, module_relative=False, + optionflags=doctest.ELLIPSIS|doctest.REPORT_ONLY_FIRST_FAILURE, + parser=LongFormDocTestParser()) + new = os.path.splitext(fn)[0] + '.html' + assert new != fn + os.system('rst2html.py %s > %s' % (fn, new)) diff --git a/paste/tests/__init__.py b/paste/tests/__init__.py deleted file mode 100644 index 792d600..0000000 --- a/paste/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/paste/tests/doctest_webapp.py b/paste/tests/doctest_webapp.py deleted file mode 100755 index a8a63c9..0000000 --- a/paste/tests/doctest_webapp.py +++ /dev/null @@ -1,439 +0,0 @@ -#!/usr/bin/env python2.4 -""" -These are functions for use when doctest-testing a document. -""" - -import subprocess -import doctest -import os -import sys -import shutil -import re -import cgi -import rfc822 -from cStringIO import StringIO -from paste import server -from paste import wsgilib -import PySourceColor - - -here = os.path.abspath(__file__) -paste_parent = os.path.dirname( - os.path.dirname(os.path.dirname(here))) - -def run(command): - data = run_raw(command) - if data: - print data - -def run_raw(command): - """ - Runs the string command, returns any output. - """ - proc = subprocess.Popen(command, shell=True, - stderr=subprocess.STDOUT, - stdout=subprocess.PIPE, env=_make_env()) - data = proc.stdout.read() - proc.wait() - while data.endswith('\n') or data.endswith('\r'): - data = data[:-1] - if data: - data = '\n'.join( - [l for l in data.splitlines() if l]) - return data - else: - return '' - -def run_command(command, name, and_print=False): - output = run_raw(command) - data = '$ %s\n%s' % (command, output) - show_file('shell-command', name, description='shell transcript', - data=data) - if and_print and output: - print output - -def _make_env(): - env = os.environ.copy() - env['PATH'] = (env.get('PATH', '') - + ':' - + os.path.join(paste_parent, 'scripts') - + ':' - + os.path.join(paste_parent, 'paste', '3rd-party', - 'sqlobject-files', 'scripts')) - env['PYTHONPATH'] = (env.get('PYTHONPATH', '') - + ':' - + paste_parent) - return env - -def clear_dir(dir): - """ - Clears (deletes) the given directory - """ - shutil.rmtree(dir, True) - -def ls(dir=None, recurse=False, indent=0): - """ - Show a directory listing - """ - dir = dir or os.getcwd() - fns = os.listdir(dir) - fns.sort() - for fn in fns: - full = os.path.join(dir, fn) - if os.path.isdir(full): - fn = fn + '/' - print ' '*indent + fn - if os.path.isdir(full) and recurse: - ls(dir=full, recurse=True, indent=indent+2) - -def make_app(dir): - os.chdir(dir) - sys.path.append(os.path.dirname(dir)) - conf, app = server.load_commandline((), allow_reload=False) - assert conf is not None, ( - "server.load_commandline requested exit with code %r" - % app) - return app - -default_app = None -default_url = None - -def set_default_app(app, url): - global default_app - global default_url - default_app = app - default_url = url - -def resource_filename(fn): - """ - Returns the filename of the resource -- generally in the directory - resources/DocumentName/fn - """ - return os.path.join( - os.path.dirname(sys.testing_document_filename), - 'resources', - os.path.splitext(os.path.basename(sys.testing_document_filename))[0], - fn) - -def show(path_info, example_name): - fn = resource_filename(example_name + '.html') - out = StringIO() - assert default_app is not None, ( - "No default_app set") - url = default_url + path_info - out.write('%s
\n' - % (url, url)) - out.write('
\n') - proc = subprocess.Popen( - ['paster', 'serve' '--server=console', '--no-verbose', - '--url=' + path_info], - stderr=subprocess.PIPE, - stdout=subprocess.PIPE, - env=_make_env()) - stdout, errors = proc.communicate() - stdout = StringIO(stdout) - headers = rfc822.Message(stdout) - content = stdout.read() - for header, value in headers.items(): - if header.lower() == 'status' and int(value.split()[0]) == 200: - continue - if header.lower() in ('content-type', 'content-length'): - continue - if (header.lower() == 'set-cookie' - and value.startswith('_SID_')): - continue - out.write('%s: %s
\n' - % (header, value)) - lines = [l for l in content.splitlines() if l.strip()] - for line in lines: - out.write(line + '\n') - if errors: - out.write('
%s
' - % errors) - out.write('
\n') - result = out.getvalue() - if not os.path.exists(fn): - f = open(fn, 'wb') - f.write(result) - f.close() - else: - f = open(fn, 'rb') - expected = f.read() - f.close() - if not html_matches(expected, result): - print 'Pages did not match. Expected from %s:' % fn - print '-'*60 - print expected - print '='*60 - print 'Actual output:' - print '-'*60 - print result - -def html_matches(pattern, text): - return True - regex = re.escape(pattern) - regex = regex.replace(r'\.\.\.', '.*') - regex = re.sub(r'0x[0-9a-f]+', '.*', regex) - regex = '^%s$' % regex - return re.search(regex, text) - -def convert_docstring_string(data): - if data.startswith('\n'): - data = data[1:] - lines = data.splitlines() - new_lines = [] - for line in lines: - if line.rstrip() == '.': - new_lines.append('') - else: - new_lines.append(line) - data = '\n'.join(new_lines) + '\n' - return data - -def create_file(path, version, data): - data = convert_docstring_string(data) - write_data(path, data) - show_file(path, version) - -def append_to_file(path, version, data): - data = convert_docstring_string(data) - f = open(path, 'a') - f.write(data) - f.close() - # I think these appends can happen so quickly (in less than a second) - # that the .pyc file doesn't appear to be expired, even though it - # is after we've made this change; so we have to get rid of the .pyc - # file: - if path.endswith('.py'): - pyc_file = path + 'c' - if os.path.exists(pyc_file): - os.unlink(pyc_file) - show_file(path, version, description='added to %s' % path, - data=data) - -def show_file(path, version, description=None, data=None): - ext = os.path.splitext(path)[1] - if data is None: - f = open(path, 'rb') - data = f.read() - f.close() - if ext == '.py': - html = ('
%s
' - % PySourceColor.str2html(data, PySourceColor.dark)) - else: - html = '
%s
' % cgi.escape(data, 1) - html = '%s
%s' % ( - description or path, html) - write_data(resource_filename('%s.%s.gen.html' % (path, version)), - html) - -def call_source_highlight(input, format): - proc = subprocess.Popen(['source-highlight', '--out-format=html', - '--no-doc', '--css=none', - '--src-lang=%s' % format], shell=False, - stdout=subprocess.PIPE) - stdout, stderr = proc.communicate(input) - result = stdout - proc.wait() - return result - - -def write_data(path, data): - dir = os.path.dirname(os.path.abspath(path)) - if not os.path.exists(dir): - os.makedirs(dir) - f = open(path, 'wb') - f.write(data) - f.close() - - -def change_file(path, changes): - f = open(os.path.abspath(path), 'rb') - lines = f.readlines() - f.close() - for change_type, line, text in changes: - if change_type == 'insert': - lines[line:line] = [text] - elif change_type == 'delete': - lines[line:text] = [] - else: - assert 0, ( - "Unknown change_type: %r" % change_type) - f = open(path, 'wb') - f.write(''.join(lines)) - f.close() - -class LongFormDocTestParser(doctest.DocTestParser): - - """ - This parser recognizes some reST comments as commands, without - prompts or expected output, like: - - .. run: - - do_this(... - ...) - """ - - _EXAMPLE_RE = re.compile(r""" - # Source consists of a PS1 line followed by zero or more PS2 lines. - (?: (?P - (?:^(?P [ ]*) >>> .*) # PS1 line - (?:\n [ ]* \.\.\. .*)*) # PS2 lines - \n? - # Want consists of any non-blank lines that do not start with PS1. - (?P (?:(?![ ]*$) # Not a blank line - (?![ ]*>>>) # Not a line starting with PS1 - .*$\n? # But any other line - )*)) - | - (?: # This is for longer commands that are prefixed with a reST - # comment like '.. run:' (two colons makes that a directive). - # These commands cannot have any output. - - (?:^\.\.[ ]*(?Prun):[ ]*\n) # Leading command/command - (?:[ ]*\n)? # Blank line following - (?P - (?:(?P [ ]+)[^ ].*$) - (?:\n [ ]+ .*)*) - ) - | - (?: # This is for shell commands - - (?P - (?:^(P [ ]*) [$] .*) # Shell line - (?:\n [ ]* [>] .*)*) # Continuation - \n? - # Want consists of any non-blank lines that do not start with $ - (?P (?:(?![ ]*$) - (?![ ]*[$]$) - .*$\n? - )*)) - """, re.MULTILINE | re.VERBOSE) - - def _parse_example(self, m, name, lineno): - r""" - Given a regular expression match from `_EXAMPLE_RE` (`m`), - return a pair `(source, want)`, where `source` is the matched - example's source code (with prompts and indentation stripped); - and `want` is the example's expected output (with indentation - stripped). - - `name` is the string's name, and `lineno` is the line number - where the example starts; both are used for error messages. - - >>> def parseit(s): - ... p = LongFormDocTestParser() - ... return p._parse_example(p._EXAMPLE_RE.search(s), '', 1) - >>> parseit('>>> 1\n1') - ('1', {}, '1', None) - >>> parseit('>>> (1\n... +1)\n2') - ('(1\n+1)', {}, '2', None) - >>> parseit('.. run:\n\n test1\n test2\n') - ('test1\ntest2', {}, '', None) - """ - # Get the example's indentation level. - runner = m.group('run') or '' - indent = len(m.group('%sindent' % runner)) - - # Divide source into lines; check that they're properly - # indented; and then strip their indentation & prompts. - source_lines = m.group('%ssource' % runner).split('\n') - if runner: - self._check_prefix(source_lines[1:], ' '*indent, name, lineno) - else: - self._check_prompt_blank(source_lines, indent, name, lineno) - self._check_prefix(source_lines[2:], ' '*indent + '.', name, lineno) - if runner: - source = '\n'.join([sl[indent:] for sl in source_lines]) - else: - source = '\n'.join([sl[indent+4:] for sl in source_lines]) - - if runner: - want = '' - exc_msg = None - else: - # Divide want into lines; check that it's properly indented; and - # then strip the indentation. Spaces before the last newline should - # be preserved, so plain rstrip() isn't good enough. - want = m.group('want') - want_lines = want.split('\n') - if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]): - del want_lines[-1] # forget final newline & spaces after it - self._check_prefix(want_lines, ' '*indent, name, - lineno + len(source_lines)) - want = '\n'.join([wl[indent:] for wl in want_lines]) - - # If `want` contains a traceback message, then extract it. - m = self._EXCEPTION_RE.match(want) - if m: - exc_msg = m.group('msg') - else: - exc_msg = None - - # Extract options from the source. - options = self._find_options(source, name, lineno) - - return source, options, want, exc_msg - - - def parse(self, string, name=''): - """ - Divide the given string into examples and intervening text, - and return them as a list of alternating Examples and strings. - Line numbers for the Examples are 0-based. The optional - argument `name` is a name identifying this string, and is only - used for error messages. - """ - string = string.expandtabs() - # If all lines begin with the same indentation, then strip it. - min_indent = self._min_indent(string) - if min_indent > 0: - string = '\n'.join([l[min_indent:] for l in string.split('\n')]) - - output = [] - charno, lineno = 0, 0 - # Find all doctest examples in the string: - for m in self._EXAMPLE_RE.finditer(string): - # Add the pre-example text to `output`. - output.append(string[charno:m.start()]) - # Update lineno (lines before this example) - lineno += string.count('\n', charno, m.start()) - # Extract info from the regexp match. - (source, options, want, exc_msg) = \ - self._parse_example(m, name, lineno) - # Create an Example, and add it to the list. - if not self._IS_BLANK_OR_COMMENT(source): - # @@: Erg, this is the only line I need to change... - output.append( doctest.Example(source, want, exc_msg, - lineno=lineno, - indent=min_indent+len(m.group('indent') or m.group('runindent')), - options=options) ) - # Update lineno (lines inside this example) - lineno += string.count('\n', m.start(), m.end()) - # Update charno. - charno = m.end() - # Add any remaining post-example text to `output`. - output.append(string[charno:]) - return output - - - -if __name__ == '__main__': - import sys - if sys.argv[1:] and sys.argv[1] == 'doctest': - doctest.testmod() - sys.exit() - if not paste_parent in sys.path: - sys.path.append(paste_parent) - for fn in sys.argv[1:]: - fn = os.path.abspath(fn) - # @@: OK, ick; but this module gets loaded twice - sys.testing_document_filename = fn - doctest.testfile( - fn, module_relative=False, - optionflags=doctest.ELLIPSIS|doctest.REPORT_ONLY_FIRST_FAILURE, - parser=LongFormDocTestParser()) - new = os.path.splitext(fn)[0] + '.html' - assert new != fn - os.system('rst2html.py %s > %s' % (fn, new)) diff --git a/paste/tests/echotest.py b/paste/tests/echotest.py deleted file mode 100755 index 885d571..0000000 --- a/paste/tests/echotest.py +++ /dev/null @@ -1,109 +0,0 @@ -""" -Tests a WSGI stack, using urllib. Queries the echo application. -""" - -import unittest -import urlparse -import urllib -import os -import sys - -class EchoTest(unittest.TestCase): - - def url(self): - if not os.environ.get('ECHO_URL'): - print 'You must set $ECHO_URL' - sys.exit(1) - url = URL(os.environ['ECHO_URL']) - return url - -class TestEnviron(EchoTest): - - def setUp(self): - self.page = self.url().fetch(environ='true') - self.environ = parse_environ(self.page) - - def testRequiredKeys(self): - environ = self.environ - url = self.url() - required_keys = 'REQUEST_METHOD SCRIPT_NAME PATH_INFO QUERY_STRING SERVER_NAME SERVER_PORT wsgi.errors wsgi.input wsgi.multiprocess wsgi.multithread wsgi.version' - for key in required_keys.split(): - assert environ.has_key(key), "Key %r missing from %r" % (key, environ) - self.assertEqual(environ['PATH_INFO'], '') - self.assertEqual(environ['SCRIPT_NAME'], url.path) - self.assertEqual(environ['REQUEST_METHOD'], 'GET') - self.assertEqual(environ['QUERY_STRING'], 'environ=true') - self.assertEqual(environ['SERVER_PORT'], str(url.port)) - self.assertEqual(environ['SERVER_NAME'], url.host) - self.assertEqual(environ['HTTP_HOST'], url.location) - assert environ['HTTP_USER_AGENT'].startswith('Python-urllib/'), \ - "HTTP_USER_AGENT should start with 'Python-urllib/': %r" % environ['HTTP_USER_AGENT'] - - def testPathInfo(self): - sub = self.url() / '' - environ = parse_environ(sub.fetch(environ='true')) - self.assertEqual(environ['PATH_INFO'], '/') - self.assertEqual(environ['SCRIPT_NAME'], self.url().path) - sub = self.url() / 'test' - environ = parse_environ(sub.fetch(environ='true')) - self.assertEqual(environ['PATH_INFO'], '/test') - self.assertEqual(environ['SCRIPT_NAME'], self.url().path) - - def test_message(self): - data = self.url().fetch(message='test') - self.assertEqual(data, 'test') - data = self.url().fetch(message='') - self.assertEqual(data, '') - -############################################################ -## Utility functions -############################################################ - -def parse_environ(page): - """ - Parses the environment that echo prints (not perfect, but good - enough). - """ - environ = {} - for line in page.splitlines(): - if '=' not in line: - # ignore second line of long lines - continue - name, value = line.split('=', 1) - environ[name] = value - return environ - -class URL: - - def __init__(self, url_string): - self.url_string = url_string - (self.scheme, self.location, self.path, self.query, - self.fragment) = urlparse.urlsplit(url_string) - if ':' in self.location: - self.host, self.port = location.split(':', 1) - else: - self.host = self.location - if self.scheme == 'http': - self.port = '80' - elif self.scheme == 'https': - self.port = '443' - else: - assert 0, "Unknown scheme: %r" % scheme - self.port = int(self.port) - - def fetch(self, **kw): - query = '&'.join(['%s=%s' % (urllib.quote(k), urllib.quote(v)) - for k, v in kw.items()]) - url = self.url_string - if query: - url += '?' + query - f = urllib.urlopen(url) - page = f.read() - f.close() - return page - - def __div__(self, path_part): - return self.__class__(self.url_string + '/' + path_part) - -if __name__ == '__main__': - unittest.main() -- cgit v1.2.1