39
|
1 import os
|
|
2 import inspect
|
|
3 import StringIO
|
|
4 import unittest
|
|
5
|
|
6 from trac.core import *
|
|
7 from trac.wiki.api import IWikiSyntaxProvider
|
|
8 from trac.wiki.formatter import Formatter, OneLinerFormatter
|
|
9 from trac.wiki.macros import WikiMacroBase
|
|
10 from trac.test import Mock, EnvironmentStub
|
|
11 from trac.util.text import to_unicode
|
|
12 from trac.util.markup import html
|
|
13
|
|
14 # We need to supply our own macro because the real macros
|
|
15 # can not be loaded using our 'fake' environment.
|
|
16
|
|
17 class HelloWorldMacro(WikiMacroBase):
|
|
18 """A dummy macro used by the unit test."""
|
|
19
|
|
20 def render_macro(self, req, name, content):
|
|
21 return 'Hello World, args = ' + content
|
|
22
|
|
23 class DivHelloWorldMacro(WikiMacroBase):
|
|
24 """A dummy macro returning a div block, used by the unit test."""
|
|
25
|
|
26 def render_macro(self, req, name, content):
|
|
27 return '<div>Hello World, args = %s</div>' % content
|
|
28
|
|
29 class DivCodeMacro(WikiMacroBase):
|
|
30 """A dummy macro returning a div block, used by the unit test."""
|
|
31
|
|
32 def render_macro(self, req, name, content):
|
|
33 return '<div class="code">Hello World, args = %s</div>' % content
|
|
34
|
|
35 class DivCodeElementMacro(WikiMacroBase):
|
|
36 """A dummy macro returning a div block, used by the unit test."""
|
|
37
|
|
38 def render_macro(self, req, name, content):
|
|
39 return html.DIV('Hello World, args = ', content, class_="code")
|
|
40
|
|
41 class SampleResolver(Component):
|
|
42 """A dummy macro returning a div block, used by the unit test."""
|
|
43
|
|
44 implements(IWikiSyntaxProvider)
|
|
45
|
|
46 def get_wiki_syntax(self):
|
|
47 return []
|
|
48
|
|
49 def get_link_resolvers(self):
|
|
50 yield ('link', self._format_link)
|
|
51
|
|
52 def _format_link(self, formatter, ns, target, label):
|
|
53 kind, module = 'text', 'stuff'
|
|
54 try:
|
|
55 kind = int(target) % 2 and 'odd' or 'even'
|
|
56 module = 'thing'
|
|
57 except ValueError:
|
|
58 pass
|
|
59 return html.A(label, class_='%s resolver' % kind,
|
|
60 href=formatter.href(module, target))
|
|
61
|
|
62
|
|
63 class WikiTestCase(unittest.TestCase):
|
|
64
|
|
65 def __init__(self, input, correct, file, line):
|
|
66 unittest.TestCase.__init__(self, 'test')
|
|
67 self.title, self.input = input.split('\n', 1)
|
|
68 if self.title:
|
|
69 self.title = self.title.strip()
|
|
70 self.correct = correct
|
|
71 self.file = file
|
|
72 self.line = line
|
|
73
|
|
74 self.env = EnvironmentStub()
|
|
75 # -- macros support
|
|
76 self.env.path = ''
|
|
77 # -- intertrac support
|
|
78 self.env.config.set('intertrac', 'trac.title', "Trac's Trac")
|
|
79 self.env.config.set('intertrac', 'trac.url',
|
|
80 "http://projects.edgewall.com/trac")
|
|
81 self.env.config.set('intertrac', 't', 'trac')
|
|
82
|
|
83 from trac.web.href import Href
|
|
84 self.req = Mock(href = Href('/'),
|
|
85 abs_href = Href('http://www.example.com/'))
|
|
86 # TODO: remove the following lines in order to discover
|
|
87 # all the places were we should use the req.href
|
|
88 # instead of env.href (will be solved by the Wikifier patch)
|
|
89 self.env.href = self.req.href
|
|
90 self.env.abs_href = self.req.abs_href
|
|
91
|
|
92 def test(self):
|
|
93 """Testing WikiFormatter"""
|
|
94 out = StringIO.StringIO()
|
|
95 formatter = self.formatter()
|
|
96 formatter.format(self.input, out)
|
|
97 v = out.getvalue().replace('\r','')
|
|
98 try:
|
|
99 self.assertEquals(self.correct, v)
|
|
100 except AssertionError, e:
|
|
101 msg = to_unicode(e)
|
|
102 import re
|
|
103 match = re.match(r"u?'(.*)' != u?'(.*)'", msg)
|
|
104 if match:
|
|
105 sep = '-' * 15
|
|
106 msg = '\n%s expected:\n%s\n%s actual:\n%s\n%s\n' \
|
|
107 % (sep, match.group(1), sep, match.group(2), sep)
|
|
108 # Tip: sometimes, 'expected' and 'actual' differ only by whitespace,
|
|
109 # then replace the above line by those two:
|
|
110 # % (sep, match.group(1).replace(' ', '.'),
|
|
111 # sep, match.group(2).replace(' ', '.'), sep)
|
|
112 msg = msg.replace(r'\n', '\n')
|
|
113 raise AssertionError( # See below for details
|
|
114 '%s\n\n%s:%s: "%s" (%s flavor)' \
|
|
115 % (msg, self.file, self.line, self.title, formatter.flavor))
|
|
116
|
|
117 def formatter(self):
|
|
118 return Formatter(self.env, self.req)
|
|
119
|
|
120 def shortDescription(self):
|
|
121 return 'Test ' + self.title
|
|
122
|
|
123
|
|
124 class OneLinerTestCase(WikiTestCase):
|
|
125 def formatter(self):
|
|
126 return OneLinerFormatter(self.env) # TODO: self.req
|
|
127
|
|
128
|
|
129 def suite(data=None, setup=None, file=__file__):
|
|
130 suite = unittest.TestSuite()
|
|
131 if not data:
|
|
132 file = os.path.join(os.path.split(file)[0], 'wiki-tests.txt')
|
|
133 data = open(file, 'r').read().decode('utf-8')
|
|
134 tests = data.split('=' * 30)
|
|
135 next_line = 1
|
|
136 line = 0
|
|
137 for test in tests:
|
|
138 if line != next_line:
|
|
139 line = next_line
|
|
140 if not test or test == '\n':
|
|
141 continue
|
|
142 next_line += len(test.split('\n')) - 1
|
|
143 blocks = test.split('-' * 30 + '\n')
|
|
144 if len(blocks) != 3:
|
|
145 continue
|
|
146 input, page, oneliner = blocks
|
|
147 tc = WikiTestCase(input, page, file, line)
|
|
148 if setup:
|
|
149 setup(tc)
|
|
150 suite.addTest(tc)
|
|
151 if oneliner:
|
|
152 tc = OneLinerTestCase(input, oneliner[:-1], file, line)
|
|
153 if setup:
|
|
154 setup(tc)
|
|
155 suite.addTest(tc)
|
|
156 return suite
|
|
157
|
|
158 if __name__ == '__main__':
|
|
159 unittest.main(defaultTest='suite')
|