4 # Author: David Goodger <goodger@python.org>
5 # Copyright: This module has been placed in the public domain.
8 Test module for statemachine.py.
14 from DocutilsTestSupport
import statemachine
18 testtext
= statemachine
.string2lines("""\
21 - This is a bullet list. First list item.
22 Second line of first para.
28 - Second list item. Example::
35 expected
= ('StateMachine1 text1 blank1 bullet1 known_indent1 '
36 'StateMachine2 text2 text2 blank2 text2 blank2 indent2 '
37 'StateMachine3 text3 blank3 finished3 finished2 '
38 'bullet1 known_indent1 '
39 'StateMachine2 text2 blank2 literalblock2(4) finished2 '
40 'text1 finished1').split()
42 item1
= [line
[2:] for line
in testtext
[2:9]]
43 item2
= [line
[2:] for line
in testtext
[9:-1]]
45 literalblock
= [line
[lbindent
:] for line
in testtext
[11:-1]]
49 class MockState(statemachine
.StateWS
):
51 patterns
= {'bullet': re
.compile(r
'- '),
53 initial_transitions
= ['bullet', ['text']]
56 def bof(self
, context
):
57 self
.levelholder
[0] += 1
58 self
.level
= self
.levelholder
[0]
59 if self
.debug
: print >>sys
.stderr
, 'StateMachine%s' % self
.level
60 return [], ['StateMachine%s' % self
.level
]
62 def blank(self
, match
, context
, next_state
):
63 result
= ['blank%s' % self
.level
]
64 if self
.debug
: print >>sys
.stderr
, 'blank%s' % self
.level
65 if context
and context
[-1] and context
[-1][-2:] == '::':
66 result
.extend(self
.literalblock())
67 return [], None, result
69 def indent(self
, match
, context
, next_state
):
70 if self
.debug
: print >>sys
.stderr
, 'indent%s' % self
.level
71 context
, next_state
, result
= statemachine
.StateWS
.indent(
72 self
, match
, context
, next_state
)
73 return context
, next_state
, ['indent%s' % self
.level
] + result
75 def known_indent(self
, match
, context
, next_state
):
76 if self
.debug
: print >>sys
.stderr
, 'known_indent%s' % self
.level
77 context
, next_state
, result
= statemachine
.StateWS
.known_indent(
78 self
, match
, context
, next_state
)
79 return context
, next_state
, ['known_indent%s' % self
.level
] + result
81 def bullet(self
, match
, context
, next_state
):
82 if self
.debug
: print >>sys
.stderr
, 'bullet%s' % self
.level
83 context
, next_state
, result \
84 = self
.known_indent(match
, context
, next_state
)
85 return [], next_state
, ['bullet%s' % self
.level
] + result
87 def text(self
, match
, context
, next_state
):
88 if self
.debug
: print >>sys
.stderr
, 'text%s' % self
.level
89 return [match
.string
], next_state
, ['text%s' % self
.level
]
91 def literalblock(self
):
92 indented
, indent
, offset
, good
= self
.state_machine
.get_indented()
93 if self
.debug
: print >>sys
.stderr
, 'literalblock%s(%s)' % (self
.level
,
95 return ['literalblock%s(%s)' % (self
.level
, indent
)]
97 def eof(self
, context
):
98 self
.levelholder
[0] -= 1
99 if self
.debug
: print >>sys
.stderr
, 'finished%s' % self
.level
100 return ['finished%s' % self
.level
]
103 class EmptySMTests(unittest
.TestCase
):
106 self
.sm
= statemachine
.StateMachine(
107 state_classes
=[], initial_state
='State')
108 self
.sm
.debug
= debug
110 def test_add_state(self
):
111 self
.sm
.add_state(statemachine
.State
)
112 self
.assertTrue(len(self
.sm
.states
) == 1)
113 self
.assertRaises(statemachine
.DuplicateStateError
, self
.sm
.add_state
,
115 self
.sm
.add_state(statemachine
.StateWS
)
116 self
.assertTrue(len(self
.sm
.states
) == 2)
118 def test_add_states(self
):
119 self
.sm
.add_states((statemachine
.State
, statemachine
.StateWS
))
120 self
.assertEqual(len(self
.sm
.states
), 2)
122 def test_get_state(self
):
123 self
.assertRaises(statemachine
.UnknownStateError
, self
.sm
.get_state
)
124 self
.sm
.add_states((statemachine
.State
, statemachine
.StateWS
))
125 self
.assertRaises(statemachine
.UnknownStateError
, self
.sm
.get_state
,
127 self
.assertTrue(isinstance(self
.sm
.get_state('State'),
129 self
.assertTrue(isinstance(self
.sm
.get_state('StateWS'),
131 self
.assertEqual(self
.sm
.current_state
, 'StateWS')
134 class EmptySMWSTests(EmptySMTests
):
137 self
.sm
= statemachine
.StateMachineWS(
138 state_classes
=[], initial_state
='State')
139 self
.sm
.debug
= debug
142 class SMWSTests(unittest
.TestCase
):
145 self
.sm
= statemachine
.StateMachineWS([MockState
], 'MockState',
147 self
.sm
.debug
= debug
148 self
.sm
.states
['MockState'].levelholder
[0] = 0
153 def test___init__(self
):
154 self
.assertEqual(self
.sm
.states
.keys(), ['MockState'])
155 self
.assertEqual(len(self
.sm
.states
['MockState'].transitions
), 4)
157 def test_get_indented(self
):
158 self
.sm
.input_lines
= statemachine
.StringList(testtext
)
159 self
.sm
.line_offset
= -1
161 indented
, offset
, good
= self
.sm
.get_known_indented(2)
162 self
.assertEqual(indented
, item1
)
163 self
.assertEqual(offset
, len(para1
))
164 self
.assertTrue(good
)
166 indented
, offset
, good
= self
.sm
.get_known_indented(2)
167 self
.assertEqual(indented
, item2
)
168 self
.assertEqual(offset
, len(para1
) + len(item1
))
169 self
.assertTrue(good
)
170 self
.sm
.previous_line(3)
172 print '\ntest_get_indented: self.sm.line:\n', self
.sm
.line
173 indented
, indent
, offset
, good
= self
.sm
.get_indented()
175 print '\ntest_get_indented: indented:\n', indented
176 self
.assertEqual(indent
, lbindent
)
177 self
.assertEqual(indented
, literalblock
)
178 self
.assertEqual(offset
, (len(para1
) + len(item1
) + len(item2
)
179 - len(literalblock
)))
180 self
.assertTrue(good
)
182 def test_get_text_block(self
):
183 self
.sm
.input_lines
= statemachine
.StringList(testtext
)
184 self
.sm
.line_offset
= -1
186 textblock
= self
.sm
.get_text_block()
187 self
.assertEqual(textblock
, testtext
[:1])
189 textblock
= self
.sm
.get_text_block()
190 self
.assertEqual(textblock
, testtext
[2:4])
192 def test_get_text_block_flush_left(self
):
193 self
.sm
.input_lines
= statemachine
.StringList(testtext
)
194 self
.sm
.line_offset
= -1
196 textblock
= self
.sm
.get_text_block(flush_left
=1)
197 self
.assertEqual(textblock
, testtext
[:1])
199 self
.assertRaises(statemachine
.UnexpectedIndentationError
,
200 self
.sm
.get_text_block
, flush_left
=1)
203 self
.assertEqual(self
.sm
.run(testtext
), expected
)
210 class EmptyStateTests(unittest
.TestCase
):
213 self
.state
= statemachine
.State(EmptyClass(), debug
=debug
)
214 self
.state
.patterns
= {'nop': 'dummy',
218 self
.state
.nop2
= self
.state
.nop3
= self
.state
.nop
220 def test_add_transitions(self
):
221 self
.assertEqual(len(self
.state
.transitions
), 0)
222 self
.state
.add_transitions(['None'], {'None': None})
223 self
.assertEqual(len(self
.state
.transitions
), 1)
224 self
.assertRaises(statemachine
.UnknownTransitionError
,
225 self
.state
.add_transitions
, ['bogus'], {})
226 self
.assertRaises(statemachine
.DuplicateTransitionError
,
227 self
.state
.add_transitions
, ['None'],
230 def test_add_transition(self
):
231 self
.assertEqual(len(self
.state
.transitions
), 0)
232 self
.state
.add_transition('None', None)
233 self
.assertEqual(len(self
.state
.transitions
), 1)
234 self
.assertRaises(statemachine
.DuplicateTransitionError
,
235 self
.state
.add_transition
, 'None', None)
237 def test_remove_transition(self
):
238 self
.assertEqual(len(self
.state
.transitions
), 0)
239 self
.state
.add_transition('None', None)
240 self
.assertEqual(len(self
.state
.transitions
), 1)
241 self
.state
.remove_transition('None')
242 self
.assertEqual(len(self
.state
.transitions
), 0)
243 self
.assertRaises(statemachine
.UnknownTransitionError
,
244 self
.state
.remove_transition
, 'None')
246 def test_make_transition(self
):
247 dummy
= re
.compile('dummy')
248 self
.assertEqual(self
.state
.make_transition('nop', 'bogus'),
249 (dummy
, self
.state
.nop
, 'bogus'))
250 self
.assertEqual(self
.state
.make_transition('nop'),
251 (dummy
, self
.state
.nop
,
252 self
.state
.__class
__.__name
__))
253 self
.assertRaises(statemachine
.TransitionPatternNotFound
,
254 self
.state
.make_transition
, 'None')
255 self
.assertRaises(statemachine
.TransitionMethodNotFound
,
256 self
.state
.make_transition
, 'bogus')
258 def test_make_transitions(self
):
259 dummy
= re
.compile('dummy')
260 self
.assertEqual(self
.state
.make_transitions(('nop', ['nop2'],
262 (['nop', 'nop2', 'nop3'],
263 {'nop': (dummy
, self
.state
.nop
,
264 self
.state
.__class
__.__name
__),
265 'nop2': (dummy
, self
.state
.nop2
,
266 self
.state
.__class
__.__name
__),
267 'nop3': (dummy
, self
.state
.nop3
, 'bogus')}))
270 class MiscTests(unittest
.TestCase
):
272 s2l_string
= "hello\tthere\thow are\tyou?\n\tI'm fine\tthanks.\n"
273 s2l_expected
= ['hello there how are you?',
275 def test_string2lines(self
):
276 self
.assertEqual(statemachine
.string2lines(self
.s2l_string
),
280 if __name__
== '__main__':