1""" 2Tests for L{nevow.testutil} -- a module of utilities for testing Nevow 3applications. 4""" 5 6import sys 7 8from unittest import TestResult 9 10from twisted.python.filepath import FilePath 11from twisted.trial.unittest import TestCase, SkipTest 12from twisted.web.http import OK, BAD_REQUEST 13 14from nevow.testutil import FakeRequest, renderPage, JavaScriptTestCase 15from nevow.testutil import NotSupported 16from nevow.url import root 17from nevow.rend import Page 18from nevow.loaders import stan 19 20 21class TestFakeRequest(TestCase): 22 """ 23 Bad tests for L{FakeRequest}. 24 25 These tests verify that L{FakeRequest} has some behavior, but not that 26 that behavior is the same as the behavior of an actual request object. 27 In other words, these tests do not actually verify the fake. They 28 should be replaced with something which verifies that L{FakeRequest} and 29 L{NevowRequest} actually have the same behavior. 30 """ 31 def test_fields(self): 32 """ 33 L{FakeRequest.fields} is C{None} for all fake requests. 34 """ 35 self.assertIdentical(FakeRequest().fields, None) 36 37 38 def test_prePathURL(self): 39 """ 40 Verify that L{FakeRequest.prePathURL} returns the prepath of the 41 requested URL. 42 """ 43 req = FakeRequest(currentSegments=['a'], uri='/a/b') 44 self.assertEqual(req.prePathURL(), 'http://localhost/a') 45 46 47 def test_prePathURLHost(self): 48 """ 49 Verify that L{FakeRequest.prePathURL} will turn the C{Host} header of 50 the request into the netloc of the returned URL, if it's present. 51 """ 52 req = FakeRequest(currentSegments=['a', 'b'], 53 uri='/a/b/c/', 54 headers={'host': 'foo.bar'}) 55 self.assertEqual(req.prePathURL(), 'http://foo.bar/a/b') 56 57 58 def test_getRootURL(self): 59 """ 60 L{FakeRequest.getRootURL} returns C{None} when 61 L{FakeRequest.rememberRootURL} has not yet been called. After 62 L{FakeRequest.rememberRootURL} has been called, 63 L{FakeRequest.getRootURL} returns the value which was passed to it. 64 """ 65 request = FakeRequest() 66 self.assertIdentical(request.getRootURL(), None) 67 request.rememberRootURL("foo/bar") 68 self.assertEqual(request.getRootURL(), "foo/bar") 69 70 71 def test_headers(self): 72 """ 73 Check that setting a header with L{FakeRequest.setHeader} actually 74 places it in the headers dictionary. 75 """ 76 host = 'divmod.com' 77 req = FakeRequest() 78 req.setHeader('host', host) 79 self.assertEqual(req.responseHeaders.getRawHeaders('host'), [host]) 80 81 82 def test_caseInsensitiveHeaders(self): 83 """ 84 L{FakeRequest.getHeader} will return the value of a header regardless 85 of casing. 86 """ 87 host = 'example.com' 88 request = FakeRequest() 89 request.requestHeaders.setRawHeaders('host', [host]) 90 self.assertEqual(request.getHeader('hOsT'), host) 91 92 93 def test_smashInitialHeaderCase(self): 94 """ 95 L{FakeRequest.getHeader} will return the value of a header specified to 96 L{FakeRequest.__init__} even if the header names have differing case. 97 """ 98 host = 'example.com' 99 request = FakeRequest(headers={'HoSt': host}) 100 self.assertEqual(request.getHeader('hOsT'), host) 101 102 103 def test_urls(self): 104 """ 105 Check that rendering URLs via L{renderPage} actually works. 106 """ 107 class _URLPage(Page): 108 docFactory = stan( 109 root.child('foo')) 110 111 def _checkForUrl(result): 112 return self.assertEquals('http://localhost/foo', result) 113 114 return renderPage(_URLPage()).addCallback(_checkForUrl) 115 116 117 def test_defaultResponseCode(self): 118 """ 119 Test that the default response code of a fake request is success. 120 """ 121 self.assertEqual(FakeRequest().code, OK) 122 123 124 def test_setResponseCode(self): 125 """ 126 Test that the response code of a fake request can be set. 127 """ 128 req = FakeRequest() 129 req.setResponseCode(BAD_REQUEST) 130 self.assertEqual(req.code, BAD_REQUEST) 131 132 133 def test_headerSeparation(self): 134 """ 135 Request headers and response headers are different things. 136 137 Test that they are handled separately. 138 """ 139 req = FakeRequest() 140 req.setHeader('foo', 'bar') 141 self.assertFalse(req.requestHeaders.hasHeader('foo')) 142 self.assertEqual(req.getHeader('foo'), None) 143 req.requestHeaders.setRawHeaders('foo', ['bar']) 144 self.assertEqual(req.getHeader('foo'), 'bar') 145 146 147 148 def test_path(self): 149 """ 150 Test that the path attribute of a fake request is set. 151 """ 152 req = FakeRequest(uri='/foo') 153 self.assertEqual(req.path, '/foo') 154 155 156 157class JavaScriptTests(TestCase): 158 """ 159 Tests for the JavaScript UnitTest runner, L{JavaScriptTestCase}. 160 """ 161 def setUp(self): 162 """ 163 Create a L{JavaScriptTestCase} and verify that its dependencies are 164 present (otherwise, skip the test). 165 """ 166 self.case = JavaScriptTestCase() 167 try: 168 self.case.checkDependencies() 169 except NotSupported: 170 raise SkipTest("Missing JS dependencies") 171 172 173 def test_unsuccessfulExit(self): 174 """ 175 Verify that an unsuccessful exit status results in an error. 176 """ 177 result = TestResult() 178 self.case.createSource = lambda testMethod: "throw new TypeError();" 179 self.case.run(result) 180 self.assertEqual(len(result.errors), 1) 181 self.assertTrue( 182 result.errors[0][1].startswith( 183 'Exception: JavaScript interpreter had error exit: ')) 184 185 186 def test_signalledExit(self): 187 """ 188 An error should be reported if the JavaScript interpreter exits because 189 it received a signal. 190 """ 191 segfault = FilePath(self.mktemp()) 192 segfault.setContent("""\ 193#!/usr/bin/python 194# Generate an unhandled SIGSEGV for this process immediately upon import. 195 196import os, signal 197os.kill(os.getpid(), signal.SIGSEGV) 198""") 199 200 def stubFinder(): 201 return sys.executable 202 def stubScript(testModule): 203 return segfault.path 204 self.case.findJavascriptInterpreter = stubFinder 205 self.case.makeScript = stubScript 206 result = TestResult() 207 self.case.run(result) 208 self.assertEqual(len(result.errors), 1) 209 self.assertEquals( 210 result.errors[0][1], 211 'Exception: JavaScript interpreter exited due to signal 11\n') 212 213 214 def test_missingJavaScriptClass(self): 215 """ 216 If a JavaScript class required by the test code is unavailable, an 217 error is added to the result object by L{JavaScriptTestCase.run}. 218 """ 219 result = TestResult() 220 self.case.testMethod = lambda: "Nevow.Test.NoSuchModule" 221 self.case.run(result) 222 self.assertEqual(len(result.errors), 1) 223