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
17 if not hasattr(unittest
.TestCase
, "assertTrue"):
18 # HACK? this changes TestCase, fixes the problem for tests executing afterwards.
19 # this tests break if run alone
20 unittest
.TestCase
.assertTrue
= unittest
.TestCase
.failUnless
23 testtext
= statemachine
.string2lines("""\
26 - This is a bullet list. First list item.
27 Second line of first para.
33 - Second list item. Example::
40 expected
= ('StateMachine1 text1 blank1 bullet1 known_indent1 '
41 'StateMachine2 text2 text2 blank2 text2 blank2 indent2 '
42 'StateMachine3 text3 blank3 finished3 finished2 '
43 'bullet1 known_indent1 '
44 'StateMachine2 text2 blank2 literalblock2(4) finished2 '
45 'text1 finished1').split()
47 item1
= [line
[2:] for line
in testtext
[2:9]]
48 item2
= [line
[2:] for line
in testtext
[9:-1]]
50 literalblock
= [line
[lbindent
:] for line
in testtext
[11:-1]]
54 class MockState(statemachine
.StateWS
):
56 patterns
= {'bullet': re
.compile(r
'- '),
58 initial_transitions
= ['bullet', ['text']]
61 def bof(self
, context
):
62 self
.levelholder
[0] += 1
63 self
.level
= self
.levelholder
[0]
64 if self
.debug
: print >>sys
.stderr
, 'StateMachine%s' % self
.level
65 return [], ['StateMachine%s' % self
.level
]
67 def blank(self
, match
, context
, next_state
):
68 result
= ['blank%s' % self
.level
]
69 if self
.debug
: print >>sys
.stderr
, 'blank%s' % self
.level
70 if context
and context
[-1] and context
[-1][-2:] == '::':
71 result
.extend(self
.literalblock())
72 return [], None, result
74 def indent(self
, match
, context
, next_state
):
75 if self
.debug
: print >>sys
.stderr
, 'indent%s' % self
.level
76 context
, next_state
, result
= statemachine
.StateWS
.indent(
77 self
, match
, context
, next_state
)
78 return context
, next_state
, ['indent%s' % self
.level
] + result
80 def known_indent(self
, match
, context
, next_state
):
81 if self
.debug
: print >>sys
.stderr
, 'known_indent%s' % self
.level
82 context
, next_state
, result
= statemachine
.StateWS
.known_indent(
83 self
, match
, context
, next_state
)
84 return context
, next_state
, ['known_indent%s' % self
.level
] + result
86 def bullet(self
, match
, context
, next_state
):
87 if self
.debug
: print >>sys
.stderr
, 'bullet%s' % self
.level
88 context
, next_state
, result \
89 = self
.known_indent(match
, context
, next_state
)
90 return [], next_state
, ['bullet%s' % self
.level
] + result
92 def text(self
, match
, context
, next_state
):
93 if self
.debug
: print >>sys
.stderr
, 'text%s' % self
.level
94 return [match
.string
], next_state
, ['text%s' % self
.level
]
96 def literalblock(self
):
97 indented
, indent
, offset
, good
= self
.state_machine
.get_indented()
98 if self
.debug
: print >>sys
.stderr
, 'literalblock%s(%s)' % (self
.level
,
100 return ['literalblock%s(%s)' % (self
.level
, indent
)]
102 def eof(self
, context
):
103 self
.levelholder
[0] -= 1
104 if self
.debug
: print >>sys
.stderr
, 'finished%s' % self
.level
105 return ['finished%s' % self
.level
]
108 class EmptySMTests(unittest
.TestCase
):
111 self
.sm
= statemachine
.StateMachine(
112 state_classes
=[], initial_state
='State')
113 self
.sm
.debug
= debug
115 def test_add_state(self
):
116 self
.sm
.add_state(statemachine
.State
)
117 self
.assertTrue(len(self
.sm
.states
) == 1)
118 self
.assertRaises(statemachine
.DuplicateStateError
, self
.sm
.add_state
,
120 self
.sm
.add_state(statemachine
.StateWS
)
121 self
.assertTrue(len(self
.sm
.states
) == 2)
123 def test_add_states(self
):
124 self
.sm
.add_states((statemachine
.State
, statemachine
.StateWS
))
125 self
.assertEqual(len(self
.sm
.states
), 2)
127 def test_get_state(self
):
128 self
.assertRaises(statemachine
.UnknownStateError
, self
.sm
.get_state
)
129 self
.sm
.add_states((statemachine
.State
, statemachine
.StateWS
))
130 self
.assertRaises(statemachine
.UnknownStateError
, self
.sm
.get_state
,
132 self
.assertTrue(isinstance(self
.sm
.get_state('State'),
134 self
.assertTrue(isinstance(self
.sm
.get_state('StateWS'),
136 self
.assertEqual(self
.sm
.current_state
, 'StateWS')
139 class EmptySMWSTests(EmptySMTests
):
142 self
.sm
= statemachine
.StateMachineWS(
143 state_classes
=[], initial_state
='State')
144 self
.sm
.debug
= debug
147 class SMWSTests(unittest
.TestCase
):
150 self
.sm
= statemachine
.StateMachineWS([MockState
], 'MockState',
152 self
.sm
.debug
= debug
153 self
.sm
.states
['MockState'].levelholder
[0] = 0
158 def test___init__(self
):
159 self
.assertEqual(self
.sm
.states
.keys(), ['MockState'])
160 self
.assertEqual(len(self
.sm
.states
['MockState'].transitions
), 4)
162 def test_get_indented(self
):
163 self
.sm
.input_lines
= statemachine
.StringList(testtext
)
164 self
.sm
.line_offset
= -1
166 indented
, offset
, good
= self
.sm
.get_known_indented(2)
167 self
.assertEqual(indented
, item1
)
168 self
.assertEqual(offset
, len(para1
))
169 self
.assertTrue(good
)
171 indented
, offset
, good
= self
.sm
.get_known_indented(2)
172 self
.assertEqual(indented
, item2
)
173 self
.assertEqual(offset
, len(para1
) + len(item1
))
174 self
.assertTrue(good
)
175 self
.sm
.previous_line(3)
177 print '\ntest_get_indented: self.sm.line:\n', self
.sm
.line
178 indented
, indent
, offset
, good
= self
.sm
.get_indented()
180 print '\ntest_get_indented: indented:\n', indented
181 self
.assertEqual(indent
, lbindent
)
182 self
.assertEqual(indented
, literalblock
)
183 self
.assertEqual(offset
, (len(para1
) + len(item1
) + len(item2
)
184 - len(literalblock
)))
185 self
.assertTrue(good
)
187 def test_get_text_block(self
):
188 self
.sm
.input_lines
= statemachine
.StringList(testtext
)
189 self
.sm
.line_offset
= -1
191 textblock
= self
.sm
.get_text_block()
192 self
.assertEqual(textblock
, testtext
[:1])
194 textblock
= self
.sm
.get_text_block()
195 self
.assertEqual(textblock
, testtext
[2:4])
197 def test_get_text_block_flush_left(self
):
198 self
.sm
.input_lines
= statemachine
.StringList(testtext
)
199 self
.sm
.line_offset
= -1
201 textblock
= self
.sm
.get_text_block(flush_left
=1)
202 self
.assertEqual(textblock
, testtext
[:1])
204 self
.assertRaises(statemachine
.UnexpectedIndentationError
,
205 self
.sm
.get_text_block
, flush_left
=1)
208 self
.assertEqual(self
.sm
.run(testtext
), expected
)
215 class EmptyStateTests(unittest
.TestCase
):
218 self
.state
= statemachine
.State(EmptyClass(), debug
=debug
)
219 self
.state
.patterns
= {'nop': 'dummy',
223 self
.state
.nop2
= self
.state
.nop3
= self
.state
.nop
225 def test_add_transitions(self
):
226 self
.assertEqual(len(self
.state
.transitions
), 0)
227 self
.state
.add_transitions(['None'], {'None': None})
228 self
.assertEqual(len(self
.state
.transitions
), 1)
229 self
.assertRaises(statemachine
.UnknownTransitionError
,
230 self
.state
.add_transitions
, ['bogus'], {})
231 self
.assertRaises(statemachine
.DuplicateTransitionError
,
232 self
.state
.add_transitions
, ['None'],
235 def test_add_transition(self
):
236 self
.assertEqual(len(self
.state
.transitions
), 0)
237 self
.state
.add_transition('None', None)
238 self
.assertEqual(len(self
.state
.transitions
), 1)
239 self
.assertRaises(statemachine
.DuplicateTransitionError
,
240 self
.state
.add_transition
, 'None', None)
242 def test_remove_transition(self
):
243 self
.assertEqual(len(self
.state
.transitions
), 0)
244 self
.state
.add_transition('None', None)
245 self
.assertEqual(len(self
.state
.transitions
), 1)
246 self
.state
.remove_transition('None')
247 self
.assertEqual(len(self
.state
.transitions
), 0)
248 self
.assertRaises(statemachine
.UnknownTransitionError
,
249 self
.state
.remove_transition
, 'None')
251 def test_make_transition(self
):
252 dummy
= re
.compile('dummy')
253 self
.assertEqual(self
.state
.make_transition('nop', 'bogus'),
254 (dummy
, self
.state
.nop
, 'bogus'))
255 self
.assertEqual(self
.state
.make_transition('nop'),
256 (dummy
, self
.state
.nop
,
257 self
.state
.__class
__.__name
__))
258 self
.assertRaises(statemachine
.TransitionPatternNotFound
,
259 self
.state
.make_transition
, 'None')
260 self
.assertRaises(statemachine
.TransitionMethodNotFound
,
261 self
.state
.make_transition
, 'bogus')
263 def test_make_transitions(self
):
264 dummy
= re
.compile('dummy')
265 self
.assertEqual(self
.state
.make_transitions(('nop', ['nop2'],
267 (['nop', 'nop2', 'nop3'],
268 {'nop': (dummy
, self
.state
.nop
,
269 self
.state
.__class
__.__name
__),
270 'nop2': (dummy
, self
.state
.nop2
,
271 self
.state
.__class
__.__name
__),
272 'nop3': (dummy
, self
.state
.nop3
, 'bogus')}))
275 class MiscTests(unittest
.TestCase
):
277 s2l_string
= "hello\tthere\thow are\tyou?\n\tI'm fine\tthanks.\n"
278 s2l_expected
= ['hello there how are you?',
280 def test_string2lines(self
):
281 self
.assertEqual(statemachine
.string2lines(self
.s2l_string
),
285 if __name__
== '__main__':