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