summaryrefslogtreecommitdiff
path: root/test/test_statemachine.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_statemachine.py')
-rwxr-xr-xtest/test_statemachine.py283
1 files changed, 283 insertions, 0 deletions
diff --git a/test/test_statemachine.py b/test/test_statemachine.py
new file mode 100755
index 000000000..4ca2a0144
--- /dev/null
+++ b/test/test_statemachine.py
@@ -0,0 +1,283 @@
+#! /usr/bin/env python
+
+# Author: David Goodger
+# Contact: goodger@users.sourceforge.net
+# Revision: $Revision$
+# Date: $Date$
+# Copyright: This module has been placed in the public domain.
+
+"""
+Test module for statemachine.py.
+"""
+
+import unittest
+import sys
+import re
+from DocutilsTestSupport import statemachine
+
+
+debug = 0
+testtext = statemachine.string2lines("""\
+First paragraph.
+
+- This is a bullet list. First list item.
+ Second line of first para.
+
+ Second para.
+
+ block quote
+
+- Second list item. Example::
+
+ a
+ literal
+ block
+
+Last paragraph.""")
+expected = ('StateMachine1 text1 blank1 bullet1 known_indent1 '
+ 'StateMachine2 text2 text2 blank2 text2 blank2 indent2 '
+ 'StateMachine3 text3 blank3 finished3 finished2 '
+ 'bullet1 known_indent1 '
+ 'StateMachine2 text2 blank2 literalblock2(4) finished2 '
+ 'text1 finished1').split()
+para1 = testtext[:2]
+item1 = [line[2:] for line in testtext[2:9]]
+item2 = [line[2:] for line in testtext[9:-1]]
+lbindent = 6
+literalblock = [line[lbindent:] for line in testtext[11:-1]]
+para2 = testtext[-1]
+
+
+class MockState(statemachine.StateWS):
+
+ patterns = {'bullet': re.compile(r'- '),
+ 'text': ''}
+ initial_transitions = ['bullet', ['text']]
+ levelholder = [0]
+
+ def bof(self, context):
+ self.levelholder[0] += 1
+ self.level = self.levelholder[0]
+ if self.debug: print >>sys.stderr, 'StateMachine%s' % self.level
+ return [], ['StateMachine%s' % self.level]
+
+ def blank(self, match, context, next_state):
+ result = ['blank%s' % self.level]
+ if self.debug: print >>sys.stderr, 'blank%s' % self.level
+ if context and context[-1] and context[-1][-2:] == '::':
+ result.extend(self.literalblock())
+ return [], None, result
+
+ def indent(self, match, context, next_state):
+ if self.debug: print >>sys.stderr, 'indent%s' % self.level
+ context, next_state, result = statemachine.StateWS.indent(
+ self, match, context, next_state)
+ return context, next_state, ['indent%s' % self.level] + result
+
+ def known_indent(self, match, context, next_state):
+ if self.debug: print >>sys.stderr, 'known_indent%s' % self.level
+ context, next_state, result = statemachine.StateWS.known_indent(
+ self, match, context, next_state)
+ return context, next_state, ['known_indent%s' % self.level] + result
+
+ def bullet(self, match, context, next_state):
+ if self.debug: print >>sys.stderr, 'bullet%s' % self.level
+ context, next_state, result \
+ = self.known_indent(match, context, next_state)
+ return [], next_state, ['bullet%s' % self.level] + result
+
+ def text(self, match, context, next_state):
+ if self.debug: print >>sys.stderr, 'text%s' % self.level
+ return [match.string], next_state, ['text%s' % self.level]
+
+ def literalblock(self):
+ indented, indent, offset, good = self.state_machine.get_indented()
+ if self.debug: print >>sys.stderr, 'literalblock%s(%s)' % (self.level,
+ indent)
+ return ['literalblock%s(%s)' % (self.level, indent)]
+
+ def eof(self, context):
+ self.levelholder[0] -= 1
+ if self.debug: print >>sys.stderr, 'finished%s' % self.level
+ return ['finished%s' % self.level]
+
+
+class EmptySMTests(unittest.TestCase):
+
+ def setUp(self):
+ self.sm = statemachine.StateMachine(
+ state_classes=[], initial_state='State')
+ self.sm.debug = debug
+
+ def test_add_state(self):
+ self.sm.add_state(statemachine.State)
+ self.assert_(len(self.sm.states) == 1)
+ self.assertRaises(statemachine.DuplicateStateError, self.sm.add_state,
+ statemachine.State)
+ self.sm.add_state(statemachine.StateWS)
+ self.assert_(len(self.sm.states) == 2)
+
+ def test_add_states(self):
+ self.sm.add_states((statemachine.State, statemachine.StateWS))
+ self.assertEqual(len(self.sm.states), 2)
+
+ def test_get_state(self):
+ self.assertRaises(statemachine.UnknownStateError, self.sm.get_state)
+ self.sm.add_states((statemachine.State, statemachine.StateWS))
+ self.assertRaises(statemachine.UnknownStateError, self.sm.get_state,
+ 'unknownState')
+ self.assert_(isinstance(self.sm.get_state('State'),
+ statemachine.State))
+ self.assert_(isinstance(self.sm.get_state('StateWS'),
+ statemachine.State))
+ self.assertEqual(self.sm.current_state, 'StateWS')
+
+
+class EmptySMWSTests(EmptySMTests):
+
+ def setUp(self):
+ self.sm = statemachine.StateMachineWS(
+ state_classes=[], initial_state='State')
+ self.sm.debug = debug
+
+
+class SMWSTests(unittest.TestCase):
+
+ def setUp(self):
+ self.sm = statemachine.StateMachineWS([MockState], 'MockState',
+ debug=debug)
+ self.sm.debug = debug
+ self.sm.states['MockState'].levelholder[0] = 0
+
+ def tearDown(self):
+ self.sm.unlink()
+
+ def test___init__(self):
+ self.assertEquals(self.sm.states.keys(), ['MockState'])
+ self.assertEquals(len(self.sm.states['MockState'].transitions), 4)
+
+ def test_get_indented(self):
+ self.sm.input_lines = statemachine.StringList(testtext)
+ self.sm.line_offset = -1
+ self.sm.next_line(3)
+ indented, offset, good = self.sm.get_known_indented(2)
+ self.assertEquals(indented, item1)
+ self.assertEquals(offset, len(para1))
+ self.failUnless(good)
+ self.sm.next_line()
+ indented, offset, good = self.sm.get_known_indented(2)
+ self.assertEquals(indented, item2)
+ self.assertEquals(offset, len(para1) + len(item1))
+ self.failUnless(good)
+ self.sm.previous_line(3)
+ if self.sm.debug:
+ print '\ntest_get_indented: self.sm.line:\n', self.sm.line
+ indented, indent, offset, good = self.sm.get_indented()
+ if self.sm.debug:
+ print '\ntest_get_indented: indented:\n', indented
+ self.assertEquals(indent, lbindent)
+ self.assertEquals(indented, literalblock)
+ self.assertEquals(offset, (len(para1) + len(item1) + len(item2)
+ - len(literalblock)))
+ self.failUnless(good)
+
+ def test_get_text_block(self):
+ self.sm.input_lines = statemachine.StringList(testtext)
+ self.sm.line_offset = -1
+ self.sm.next_line()
+ textblock = self.sm.get_text_block()
+ self.assertEquals(textblock, testtext[:1])
+ self.sm.next_line(2)
+ textblock = self.sm.get_text_block()
+ self.assertEquals(textblock, testtext[2:4])
+
+ def test_get_text_block_flush_left(self):
+ self.sm.input_lines = statemachine.StringList(testtext)
+ self.sm.line_offset = -1
+ self.sm.next_line()
+ textblock = self.sm.get_text_block(flush_left=1)
+ self.assertEquals(textblock, testtext[:1])
+ self.sm.next_line(2)
+ self.assertRaises(statemachine.UnexpectedIndentationError,
+ self.sm.get_text_block, flush_left=1)
+
+ def test_run(self):
+ self.assertEquals(self.sm.run(testtext), expected)
+
+
+class EmptyClass:
+ pass
+
+
+class EmptyStateTests(unittest.TestCase):
+
+ def setUp(self):
+ self.state = statemachine.State(EmptyClass(), debug=debug)
+ self.state.patterns = {'nop': 'dummy',
+ 'nop2': 'dummy',
+ 'nop3': 'dummy',
+ 'bogus': 'dummy'}
+ self.state.nop2 = self.state.nop3 = self.state.nop
+
+ def test_add_transitions(self):
+ self.assertEquals(len(self.state.transitions), 0)
+ self.state.add_transitions(['None'], {'None': None})
+ self.assertEquals(len(self.state.transitions), 1)
+ self.assertRaises(statemachine.UnknownTransitionError,
+ self.state.add_transitions, ['bogus'], {})
+ self.assertRaises(statemachine.DuplicateTransitionError,
+ self.state.add_transitions, ['None'],
+ {'None': None})
+
+ def test_add_transition(self):
+ self.assertEquals(len(self.state.transitions), 0)
+ self.state.add_transition('None', None)
+ self.assertEquals(len(self.state.transitions), 1)
+ self.assertRaises(statemachine.DuplicateTransitionError,
+ self.state.add_transition, 'None', None)
+
+ def test_remove_transition(self):
+ self.assertEquals(len(self.state.transitions), 0)
+ self.state.add_transition('None', None)
+ self.assertEquals(len(self.state.transitions), 1)
+ self.state.remove_transition('None')
+ self.assertEquals(len(self.state.transitions), 0)
+ self.assertRaises(statemachine.UnknownTransitionError,
+ self.state.remove_transition, 'None')
+
+ def test_make_transition(self):
+ dummy = re.compile('dummy')
+ self.assertEquals(self.state.make_transition('nop', 'bogus'),
+ (dummy, self.state.nop, 'bogus'))
+ self.assertEquals(self.state.make_transition('nop'),
+ (dummy, self.state.nop,
+ self.state.__class__.__name__))
+ self.assertRaises(statemachine.TransitionPatternNotFound,
+ self.state.make_transition, 'None')
+ self.assertRaises(statemachine.TransitionMethodNotFound,
+ self.state.make_transition, 'bogus')
+
+ def test_make_transitions(self):
+ dummy = re.compile('dummy')
+ self.assertEquals(self.state.make_transitions(('nop', ['nop2'],
+ ('nop3', 'bogus'))),
+ (['nop', 'nop2', 'nop3'],
+ {'nop': (dummy, self.state.nop,
+ self.state.__class__.__name__),
+ 'nop2': (dummy, self.state.nop2,
+ self.state.__class__.__name__),
+ 'nop3': (dummy, self.state.nop3, 'bogus')}))
+
+
+class MiscTests(unittest.TestCase):
+
+ s2l_string = "hello\tthere\thow are\tyou?\n\tI'm fine\tthanks.\n"
+ s2l_expected = ['hello there how are you?',
+ " I'm fine thanks."]
+ def test_string2lines(self):
+ self.assertEquals(statemachine.string2lines(self.s2l_string),
+ self.s2l_expected)
+
+
+if __name__ == '__main__':
+ unittest.main()