Fixes in linepsacing doc.
[docutils.git] / test / test_statemachine.py
blob4ca2a0144392e8298a6d25c49466c4f3a7e08e1e
1 #! /usr/bin/env python
3 # Author: David Goodger
4 # Contact: goodger@users.sourceforge.net
5 # Revision: $Revision$
6 # Date: $Date$
7 # Copyright: This module has been placed in the public domain.
9 """
10 Test module for statemachine.py.
11 """
13 import unittest
14 import sys
15 import re
16 from DocutilsTestSupport import statemachine
19 debug = 0
20 testtext = statemachine.string2lines("""\
21 First paragraph.
23 - This is a bullet list. First list item.
24 Second line of first para.
26 Second para.
28 block quote
30 - Second list item. Example::
33 literal
34 block
36 Last paragraph.""")
37 expected = ('StateMachine1 text1 blank1 bullet1 known_indent1 '
38 'StateMachine2 text2 text2 blank2 text2 blank2 indent2 '
39 'StateMachine3 text3 blank3 finished3 finished2 '
40 'bullet1 known_indent1 '
41 'StateMachine2 text2 blank2 literalblock2(4) finished2 '
42 'text1 finished1').split()
43 para1 = testtext[:2]
44 item1 = [line[2:] for line in testtext[2:9]]
45 item2 = [line[2:] for line in testtext[9:-1]]
46 lbindent = 6
47 literalblock = [line[lbindent:] for line in testtext[11:-1]]
48 para2 = testtext[-1]
51 class MockState(statemachine.StateWS):
53 patterns = {'bullet': re.compile(r'- '),
54 'text': ''}
55 initial_transitions = ['bullet', ['text']]
56 levelholder = [0]
58 def bof(self, context):
59 self.levelholder[0] += 1
60 self.level = self.levelholder[0]
61 if self.debug: print >>sys.stderr, 'StateMachine%s' % self.level
62 return [], ['StateMachine%s' % self.level]
64 def blank(self, match, context, next_state):
65 result = ['blank%s' % self.level]
66 if self.debug: print >>sys.stderr, 'blank%s' % self.level
67 if context and context[-1] and context[-1][-2:] == '::':
68 result.extend(self.literalblock())
69 return [], None, result
71 def indent(self, match, context, next_state):
72 if self.debug: print >>sys.stderr, 'indent%s' % self.level
73 context, next_state, result = statemachine.StateWS.indent(
74 self, match, context, next_state)
75 return context, next_state, ['indent%s' % self.level] + result
77 def known_indent(self, match, context, next_state):
78 if self.debug: print >>sys.stderr, 'known_indent%s' % self.level
79 context, next_state, result = statemachine.StateWS.known_indent(
80 self, match, context, next_state)
81 return context, next_state, ['known_indent%s' % self.level] + result
83 def bullet(self, match, context, next_state):
84 if self.debug: print >>sys.stderr, 'bullet%s' % self.level
85 context, next_state, result \
86 = self.known_indent(match, context, next_state)
87 return [], next_state, ['bullet%s' % self.level] + result
89 def text(self, match, context, next_state):
90 if self.debug: print >>sys.stderr, 'text%s' % self.level
91 return [match.string], next_state, ['text%s' % self.level]
93 def literalblock(self):
94 indented, indent, offset, good = self.state_machine.get_indented()
95 if self.debug: print >>sys.stderr, 'literalblock%s(%s)' % (self.level,
96 indent)
97 return ['literalblock%s(%s)' % (self.level, indent)]
99 def eof(self, context):
100 self.levelholder[0] -= 1
101 if self.debug: print >>sys.stderr, 'finished%s' % self.level
102 return ['finished%s' % self.level]
105 class EmptySMTests(unittest.TestCase):
107 def setUp(self):
108 self.sm = statemachine.StateMachine(
109 state_classes=[], initial_state='State')
110 self.sm.debug = debug
112 def test_add_state(self):
113 self.sm.add_state(statemachine.State)
114 self.assert_(len(self.sm.states) == 1)
115 self.assertRaises(statemachine.DuplicateStateError, self.sm.add_state,
116 statemachine.State)
117 self.sm.add_state(statemachine.StateWS)
118 self.assert_(len(self.sm.states) == 2)
120 def test_add_states(self):
121 self.sm.add_states((statemachine.State, statemachine.StateWS))
122 self.assertEqual(len(self.sm.states), 2)
124 def test_get_state(self):
125 self.assertRaises(statemachine.UnknownStateError, self.sm.get_state)
126 self.sm.add_states((statemachine.State, statemachine.StateWS))
127 self.assertRaises(statemachine.UnknownStateError, self.sm.get_state,
128 'unknownState')
129 self.assert_(isinstance(self.sm.get_state('State'),
130 statemachine.State))
131 self.assert_(isinstance(self.sm.get_state('StateWS'),
132 statemachine.State))
133 self.assertEqual(self.sm.current_state, 'StateWS')
136 class EmptySMWSTests(EmptySMTests):
138 def setUp(self):
139 self.sm = statemachine.StateMachineWS(
140 state_classes=[], initial_state='State')
141 self.sm.debug = debug
144 class SMWSTests(unittest.TestCase):
146 def setUp(self):
147 self.sm = statemachine.StateMachineWS([MockState], 'MockState',
148 debug=debug)
149 self.sm.debug = debug
150 self.sm.states['MockState'].levelholder[0] = 0
152 def tearDown(self):
153 self.sm.unlink()
155 def test___init__(self):
156 self.assertEquals(self.sm.states.keys(), ['MockState'])
157 self.assertEquals(len(self.sm.states['MockState'].transitions), 4)
159 def test_get_indented(self):
160 self.sm.input_lines = statemachine.StringList(testtext)
161 self.sm.line_offset = -1
162 self.sm.next_line(3)
163 indented, offset, good = self.sm.get_known_indented(2)
164 self.assertEquals(indented, item1)
165 self.assertEquals(offset, len(para1))
166 self.failUnless(good)
167 self.sm.next_line()
168 indented, offset, good = self.sm.get_known_indented(2)
169 self.assertEquals(indented, item2)
170 self.assertEquals(offset, len(para1) + len(item1))
171 self.failUnless(good)
172 self.sm.previous_line(3)
173 if self.sm.debug:
174 print '\ntest_get_indented: self.sm.line:\n', self.sm.line
175 indented, indent, offset, good = self.sm.get_indented()
176 if self.sm.debug:
177 print '\ntest_get_indented: indented:\n', indented
178 self.assertEquals(indent, lbindent)
179 self.assertEquals(indented, literalblock)
180 self.assertEquals(offset, (len(para1) + len(item1) + len(item2)
181 - len(literalblock)))
182 self.failUnless(good)
184 def test_get_text_block(self):
185 self.sm.input_lines = statemachine.StringList(testtext)
186 self.sm.line_offset = -1
187 self.sm.next_line()
188 textblock = self.sm.get_text_block()
189 self.assertEquals(textblock, testtext[:1])
190 self.sm.next_line(2)
191 textblock = self.sm.get_text_block()
192 self.assertEquals(textblock, testtext[2:4])
194 def test_get_text_block_flush_left(self):
195 self.sm.input_lines = statemachine.StringList(testtext)
196 self.sm.line_offset = -1
197 self.sm.next_line()
198 textblock = self.sm.get_text_block(flush_left=1)
199 self.assertEquals(textblock, testtext[:1])
200 self.sm.next_line(2)
201 self.assertRaises(statemachine.UnexpectedIndentationError,
202 self.sm.get_text_block, flush_left=1)
204 def test_run(self):
205 self.assertEquals(self.sm.run(testtext), expected)
208 class EmptyClass:
209 pass
212 class EmptyStateTests(unittest.TestCase):
214 def setUp(self):
215 self.state = statemachine.State(EmptyClass(), debug=debug)
216 self.state.patterns = {'nop': 'dummy',
217 'nop2': 'dummy',
218 'nop3': 'dummy',
219 'bogus': 'dummy'}
220 self.state.nop2 = self.state.nop3 = self.state.nop
222 def test_add_transitions(self):
223 self.assertEquals(len(self.state.transitions), 0)
224 self.state.add_transitions(['None'], {'None': None})
225 self.assertEquals(len(self.state.transitions), 1)
226 self.assertRaises(statemachine.UnknownTransitionError,
227 self.state.add_transitions, ['bogus'], {})
228 self.assertRaises(statemachine.DuplicateTransitionError,
229 self.state.add_transitions, ['None'],
230 {'None': None})
232 def test_add_transition(self):
233 self.assertEquals(len(self.state.transitions), 0)
234 self.state.add_transition('None', None)
235 self.assertEquals(len(self.state.transitions), 1)
236 self.assertRaises(statemachine.DuplicateTransitionError,
237 self.state.add_transition, 'None', None)
239 def test_remove_transition(self):
240 self.assertEquals(len(self.state.transitions), 0)
241 self.state.add_transition('None', None)
242 self.assertEquals(len(self.state.transitions), 1)
243 self.state.remove_transition('None')
244 self.assertEquals(len(self.state.transitions), 0)
245 self.assertRaises(statemachine.UnknownTransitionError,
246 self.state.remove_transition, 'None')
248 def test_make_transition(self):
249 dummy = re.compile('dummy')
250 self.assertEquals(self.state.make_transition('nop', 'bogus'),
251 (dummy, self.state.nop, 'bogus'))
252 self.assertEquals(self.state.make_transition('nop'),
253 (dummy, self.state.nop,
254 self.state.__class__.__name__))
255 self.assertRaises(statemachine.TransitionPatternNotFound,
256 self.state.make_transition, 'None')
257 self.assertRaises(statemachine.TransitionMethodNotFound,
258 self.state.make_transition, 'bogus')
260 def test_make_transitions(self):
261 dummy = re.compile('dummy')
262 self.assertEquals(self.state.make_transitions(('nop', ['nop2'],
263 ('nop3', 'bogus'))),
264 (['nop', 'nop2', 'nop3'],
265 {'nop': (dummy, self.state.nop,
266 self.state.__class__.__name__),
267 'nop2': (dummy, self.state.nop2,
268 self.state.__class__.__name__),
269 'nop3': (dummy, self.state.nop3, 'bogus')}))
272 class MiscTests(unittest.TestCase):
274 s2l_string = "hello\tthere\thow are\tyou?\n\tI'm fine\tthanks.\n"
275 s2l_expected = ['hello there how are you?',
276 " I'm fine thanks."]
277 def test_string2lines(self):
278 self.assertEquals(statemachine.string2lines(self.s2l_string),
279 self.s2l_expected)
282 if __name__ == '__main__':
283 unittest.main()