1 # This file is part of the Enkel web programming library.
3 # Copyright (C) 2007 Espen Angell Kristiansen (espeak@users.sourceforge.net)
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 from unittest
import TestCase
20 from cStringIO
import StringIO
21 from sys
import exc_info
23 from enkel
.wansgli
.apprunner
import run_app
, AppError
, Response
24 from enkel
.wansgli
.testhelpers
import unit_case_suite
, run_suite
27 HEAD
= "HTTP/1.1 200 OK\r\ncontent-type: text/plain\r\n"
28 ERRHEAD
= "HTTP/1.1 500 ERROR\r\ncontent-type: text/plain\r\n"
30 def only_header_app(env
, start_response
):
31 start_response("200 OK", [("Content-type", "text/plain")])
32 return list() # return empty list
34 def simple_app(env
, start_response
):
35 start_response("200 OK", [("Content-type", "text/plain")])
38 def using_write_app(env
, start_response
):
39 """ WSGI app for testing of the write function. """
40 write
= start_response("200 OK", [("Content-type", "text/plain")])
44 def mixing_write_app(env
, start_response
):
45 """ WSGI app for tesing of mixing using the write function and iterator. """
46 write
= start_response("200 OK", [("Content-type", "text/plain")])
47 write("Mixing write... ")
48 return [" ...and iterator."]
50 def double_response_error_app(env
, start_response
):
51 """ WSGI app for testing the situation when an error occurs BEFORE
52 HTTP headers are sent to the browser and a traceback IS NOT supplied.
54 This should produce an error, and the same will happen if start_response
55 is called after HTTP headers are sent. """
56 start_response("200 OK", [("Content-type", "text/plain")])
57 start_response("500 ERROR", [("Content-type", "text/plain")])
58 return list() # return empty list
60 def double_response_ok_app(env
, start_response
):
61 """ WSGI app for testing the situation when an error occurs BEFORE
62 HTTP headers are sent to the browser and a traceback is supplied.
65 start_response("200 OK", [("Content-type", "text/plain")])
69 start_response("500 ERROR", [("Content-type", "text/plain")],
71 return list() # return empty list
74 class DoubleResponseErrInResponse(object):
75 """ WSGI app for testing the situation when an error occurs AFTER
76 HTTP headers are sent to the browser and a traceback is supplied.
78 Should re-raise the ValueError raised when "four" is sent to the
81 def __init__(self
, env
, start_response
):
82 start_response("200 OK", [("Content-type", "text/plain")])
83 self
.it
= [1, "2", 3, "four", 5, "6"].__iter
__()
84 self
.start_response
= start_response
89 yield str(int(d
)) # will fail on "four"
91 self
.start_response("500 ERROR",
92 [("Content-type", "text/plain")],
96 def noiter_app(env
, start_response
):
97 """ An app that does not return an iterator. This is an error,
98 and should raise AppError. """
99 start_response("200 OK", [("Content-type", "text/plain")])
103 def override_defaultheader(env
, start_response
):
104 """ An app that overrides the default HTTP header "server".
105 This should result in only one "server" header with the new value.
107 start_response("200 OK", [
108 ("Content-type", "text/plain"),
115 class TestApprunner(TestCase
):
116 """ Tests the entire apprunner module. """
118 self
.buf
= StringIO()
119 self
.env
= dict(SERVER_PROTOCOL
="HTTP/1.1")
120 self
.sr
= Response(self
.buf
, self
.env
)
122 def test_only_header(self
):
123 run_app(only_header_app
, self
.sr
)
124 b
= self
.buf
.getvalue()
125 self
.assert_(b
.startswith(HEAD
))
127 def test_simple(self
):
128 run_app(simple_app
, self
.sr
)
129 b
= self
.buf
.getvalue()
130 self
.assert_(b
.startswith(HEAD
))
131 self
.assert_(b
.endswith("Simple app"))
133 def test_using_write(self
):
134 run_app(using_write_app
, self
.sr
)
135 b
= self
.buf
.getvalue()
136 self
.assert_(b
.startswith(HEAD
))
137 self
.assert_(b
.endswith("Using write"))
140 def test_mixing_write(self
):
141 run_app(mixing_write_app
, self
.sr
)
142 b
= self
.buf
.getvalue()
143 self
.assert_(b
.startswith(HEAD
))
144 self
.assert_(b
.endswith("Mixing write... ...and iterator."))
146 def test_double_response_error(self
):
147 self
.assertRaises(AppError
, run_app
,
148 double_response_error_app
, self
.sr
)
150 def test_double_response_ok(self
):
151 run_app(double_response_ok_app
, self
.sr
)
152 b
= self
.buf
.getvalue()
153 self
.assert_(b
.startswith(ERRHEAD
))
155 def testDoubleResponseErrInResponse(self
):
156 self
.assertRaises(ValueError, run_app
,
157 DoubleResponseErrInResponse
, self
.sr
)
159 def test_noiter(self
):
160 self
.assertRaises(AppError
, run_app
,
165 return unit_case_suite(TestApprunner
)
167 if __name__
== '__main__':