3 # Author: David Goodger
4 # Contact: goodger@users.sourceforge.net
7 # Copyright: This module has been placed in the public domain.
10 Test module for statemachine.py.
16 from DocutilsTestSupport
import statemachine
20 testtext
= statemachine
.string2lines("""\
23 - This is a bullet list. First list item.
24 Second line of first para.
30 - Second list item. Example::
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()
44 item1
= [line
[2:] for line
in testtext
[2:9]]
45 item2
= [line
[2:] for line
in testtext
[9:-1]]
47 literalblock
= [line
[lbindent
:] for line
in testtext
[11:-1]]
51 class MockState(statemachine
.StateWS
):
53 patterns
= {'bullet': re
.compile(r
'- '),
55 initial_transitions
= ['bullet', ['text']]
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
,
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
):
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
,
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
,
129 self
.assert_(isinstance(self
.sm
.get_state('State'),
131 self
.assert_(isinstance(self
.sm
.get_state('StateWS'),
133 self
.assertEqual(self
.sm
.current_state
, 'StateWS')
136 class EmptySMWSTests(EmptySMTests
):
139 self
.sm
= statemachine
.StateMachineWS(
140 state_classes
=[], initial_state
='State')
141 self
.sm
.debug
= debug
144 class SMWSTests(unittest
.TestCase
):
147 self
.sm
= statemachine
.StateMachineWS([MockState
], 'MockState',
149 self
.sm
.debug
= debug
150 self
.sm
.states
['MockState'].levelholder
[0] = 0
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
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
)
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)
174 print '\ntest_get_indented: self.sm.line:\n', self
.sm
.line
175 indented
, indent
, offset
, good
= self
.sm
.get_indented()
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
188 textblock
= self
.sm
.get_text_block()
189 self
.assertEquals(textblock
, testtext
[:1])
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
198 textblock
= self
.sm
.get_text_block(flush_left
=1)
199 self
.assertEquals(textblock
, testtext
[:1])
201 self
.assertRaises(statemachine
.UnexpectedIndentationError
,
202 self
.sm
.get_text_block
, flush_left
=1)
205 self
.assertEquals(self
.sm
.run(testtext
), expected
)
212 class EmptyStateTests(unittest
.TestCase
):
215 self
.state
= statemachine
.State(EmptyClass(), debug
=debug
)
216 self
.state
.patterns
= {'nop': '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'],
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'],
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?',
277 def test_string2lines(self
):
278 self
.assertEquals(statemachine
.string2lines(self
.s2l_string
),
282 if __name__
== '__main__':