1# Copyright (c) 2008 Divmod. See LICENSE for details. 2 3""" 4Tests for L{nevow.livetrial} and L{nevow.scripts.nit}. 5""" 6 7import sys 8 9from twisted.trial.unittest import TestCase 10from twisted.python.failure import Failure 11 12from nevow.appserver import NevowSite 13from nevow.testutil import FragmentWrapper, renderLivePage 14from nevow.livetrial.testcase import TestSuite, TestError 15from nevow.livetrial.runner import TestFrameworkRoot 16from nevow.scripts import nit 17 18MESSAGE = u'I am an error' 19 20 21 22class _DummyErrorHolder(object): 23 """ 24 A dummy object that implements the parts of the ErrorHolder API we use, 25 supplying an appropriate Failure. 26 """ 27 28 def createFailure(self): 29 """Create a Failure with traceback and all.""" 30 try: 31 raise Exception(MESSAGE) 32 except Exception: 33 return Failure() 34 35 36 def run(self, thing): 37 thing.addError(self, self.createFailure()) 38 39 40 41class _DummySuite(TestSuite): 42 """A dummy test suite containing a dummy Failure holder.""" 43 44 holderType = _DummyErrorHolder 45 46 def __init__(self): 47 self.name = 'Dummy Suite' 48 holder = _DummyErrorHolder() 49 self.tests = [holder] 50 51 52 53class NevowInteractiveTesterTest(TestCase): 54 55 def test_gatherError(self): 56 """ 57 Attempt collection of tests in the presence of an Failure that has 58 occurred during trial's collection. 59 """ 60 suite = _DummySuite() 61 instances = suite.gatherInstances() 62 te = instances[0] 63 self.assertIdentical(type(te), TestError) 64 65 66 def test_errorRendering(self): 67 te = TestError(_DummyErrorHolder()) 68 return renderLivePage(FragmentWrapper(te)).addCallback( 69 lambda output: self.assertIn(MESSAGE, output)) 70 71 72 def test_portOption(self): 73 """ 74 L{nit.NitOptions.parseOptions} accepts the I{--port} option and sets 75 the port number based on it. 76 """ 77 options = nit.NitOptions() 78 options.parseOptions(['--port', '1234']) 79 self.assertEqual(options['port'], 1234) 80 81 82 def test_portOptionDefault(self): 83 """ 84 If no I{--port} option is given, a default port number is used. 85 """ 86 options = nit.NitOptions() 87 options.parseOptions([]) 88 self.assertEqual(options['port'], 8080) 89 90 91 def test_testModules(self): 92 """ 93 All extra positional arguments are interpreted as test modules. 94 """ 95 options = nit.NitOptions() 96 options.parseOptions(['foo', 'bar']) 97 self.assertEqual(options['testmodules'], ('foo', 'bar')) 98 99 100 def test_getSuite(self): 101 """ 102 L{nit._getSuite} returns a L{nevow.livetrial.testcase.TestSuite} with 103 L{TestCase} instances added to it as specified by the list of module 104 names passed to it. 105 """ 106 suite = nit._getSuite(['nevow.test.livetest_athena']) 107 self.assertTrue(suite.tests[0].tests) 108 109 110 def test_runInvalidOptions(self): 111 """ 112 L{nit.run} raises L{SystemExit} if invalid options are used. 113 """ 114 self.patch(sys, 'argv', ["nit", "--foo"]) 115 self.assertRaises(SystemExit, nit.run) 116 117 118 def test_runWithoutModules(self): 119 """ 120 If no modules to test are given on the command line, L{nit.run} raises 121 L{SystemExit}. 122 """ 123 self.patch(sys, 'argv', ['nit']) 124 self.assertRaises(SystemExit, nit.run) 125 126 127 def test_run(self): 128 """ 129 Given a valid port number and a test module, L{nit.run} starts logging 130 to stdout, starts a L{NevowSite} listening on the specified port 131 serving a L{TestFrameworkRoot}, and runs the reactor. 132 """ 133 class FakeReactor: 134 def listenTCP(self, port, factory): 135 events.append(('listen', port, factory)) 136 137 def run(self): 138 events.append(('run',)) 139 140 events = [] 141 self.patch( 142 nit, 'startLogging', lambda out: events.append(('logging', out))) 143 self.patch(nit, 'reactor', FakeReactor()) 144 self.patch(sys, 'argv', ['nit', '--port', '123', 'nevow']) 145 nit.run() 146 self.assertEqual(events[0], ('logging', sys.stdout)) 147 self.assertEqual(events[1][:2], ('listen', 123)) 148 self.assertTrue(isinstance(events[1][2], NevowSite)) 149 self.assertTrue(isinstance(events[1][2].resource, TestFrameworkRoot)) 150 self.assertEqual(events[2], ('run',)) 151 152