1from twisted.python import filepath
2
3from nevow import athena, loaders, tags, rend, url, static, util
4
5staticData = filepath.FilePath(__file__).parent().child('static')
6
7class TestSuiteFragment(athena.LiveFragment):
8    jsClass = u'Nevow.Athena.Test.TestSuite'
9    docFactory = loaders.stan(tags.invisible(render=tags.directive('tests')))
10
11    def __init__(self, suite):
12        super(TestSuiteFragment, self).__init__()
13        self.suite = suite
14        self.testInstances = suite.gatherInstances()
15
16
17    def gatherTests(self, testInstances):
18        suiteTag = tags.div()
19        for test in testInstances:
20            if isinstance(test, list):
21                suiteTag[self.gatherTests(testInstances)]
22            else:
23                test.setFragmentParent(self)
24                suiteTag[test]
25        return suiteTag
26
27
28    def gatherHead(self):
29        head = []
30        def gather(testInstances):
31            for test in testInstances:
32                if isinstance(test, list):
33                    head.extend(gather(test))
34                else:
35                    head.append(test.head())
36        gather(self.testInstances)
37        return filter(None, head)
38
39
40    def render_tests(self, ctx, data):
41        return ctx.tag[self.gatherTests(self.testInstances)]
42
43
44
45class TestRunner(TestSuiteFragment):
46    jsClass = u'Nevow.Athena.Test.TestRunner'
47    docFactory = loaders.stan(
48        tags.div(_class='test-runner', render=tags.directive('liveFragment'))[
49            tags.form(action='#')[
50                athena.handler(event='onsubmit', handler='runWithDefaults'),
51                tags.input(type='submit', value='Run Tests')],
52            tags.div[
53                tags.div[
54                    tags.div['Tests passed: ', tags.span(_class='test-success-count')[0]],
55                    tags.div['Tests failed: ', tags.span(_class='test-failure-count')[0]],
56                    tags.div['Tests completed in: ', tags.span(_class='test-time')['-']],
57                    tags.div(render=tags.directive('debug'))],
58                tags.hr,
59                tags.div[tags.span(_class='test-results')],
60                tags.hr,
61                tags.div(render=tags.directive('tests'))]])
62
63
64    def render_debug(self, ctx, data):
65        f = athena.IntrospectionFragment()
66        f.setFragmentParent(self)
67        return f
68
69
70
71DOCTYPE_XHTML = (
72    '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" '
73    '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">')
74
75class TestFramework(athena.LivePage):
76    addSlash = True
77    docFactory = loaders.stan([
78        tags.xml(DOCTYPE_XHTML),
79        tags.html[
80            tags.head(render=tags.directive('liveglue'))[
81                tags.link(rel='stylesheet', href='livetest.css'),
82                tags.directive('head')],
83            tags.body[
84                tags.invisible(render=tags.directive('runner'))]]])
85
86    def __init__(self, testSuite):
87        super(TestFramework, self).__init__()
88        self.testSuite = testSuite
89        self.children = {
90            'livetest.css': static.File(util.resource_filename('nevow.livetrial', 'livetest.css')),
91        }
92
93
94    def beforeRender(self, ctx):
95        self.runner = TestRunner(self.testSuite)
96
97
98    def render_runner(self, ctx, data):
99        self.runner.setFragmentParent(self)
100        return self.runner
101
102
103    def render_head(self, ctx, data):
104        return self.runner.gatherHead()
105
106
107class TestFrameworkRoot(rend.Page):
108    def child_app(self, ctx):
109        return TestFramework(self.original)
110    child_ = url.URL.fromString('/app')
111