def test_matching_transition_applied(self): t = Transition(fr='start', to='end', match='test') state = 'start' stack = [] token = 'test' assert t.apply(state, stack, token) == 'end'
def test_matching_on_both_input_and_stack(self): t = Transition(fr='start', to='end', match='test', stack_match='t') state = 'start' stack = [('t', 'value')] token = 'test' assert t.apply(state, stack, token) == 'end'
def test_match_on_stack_required(self): t = Transition(fr='start', to='end', match='test', stack_match='t') state = 'start' stack = [('x', 'value')] token = 'test' assert t.apply(state, stack, token) is None
def test_ignored_if_no_match(self): t = Transition(fr='start', to='end', match='testing') state = 'start' stack = [] token = 'test' assert t.apply(state, stack, token) is None
def test_pop_before_push(self): t = Transition(fr='start', to='end', match='test', pop=True, param='t') state = 'start' stack = [('x', 'value')] token = 'test' assert t.apply(state, stack, token) == 'end' assert len(stack) == 1 and stack[0] == ('t', 'test')
def test_pop_ignored_if_stack_empty(self): t = Transition(fr='start', to='end', match='test', pop=True) state = 'start' stack = [] token = 'test' assert t.apply(state, stack, token) is None assert len(stack) == 0
def test_stack_pop(self): t = Transition(fr='start', to='end', match='test', pop=True) state = 'start' stack = [('x', 'value')] token = 'test' t.apply(state, stack, token) assert len(stack) == 0
def test_stack_push(self): t = Transition(fr='start', to='end', match='test', param='t') state = 'start' stack = [] token = 'test' t.apply(state, stack, token) assert len(stack) == 1 and stack[0] == ('t', 'test')
def test_parsing_succeeds_if_end_state_reached(self): p = Parser(start='start', end='end', transitions=[ Transition(fr='start', to='next', match='test1'), Transition(fr='start', to='end', match='test'), Transition(fr='start', to='other', match='test') ]) args = p.parse('test') assert len(args) == 0
def test_simple_param_extraction(self): p = Parser(start='start', end='end', transitions=[ Transition(fr='start', to='greet', match='hi'), Transition(fr='greet', to='greet', match='Im'), Transition(fr='greet', to='end', match='.*', param='name') ]) args = p.parse('hi I\'m tester') assert 'name' in args and args['name'] == 'tester'
def test_parsing_fails_if_no_transition_applies(self): p = Parser( start='start', end='end', transitions=[Transition(fr='start', to='end', match='test')]) self.assertRaises(ParseError, p.parse, 'invalid')
def test_parsing_fails_if_end_state_not_reached(self): p = Parser( start='start', end='end', transitions=[Transition(fr='start', to='other', match='test')]) self.assertRaises(ParseError, p.parse, 'test')
def test_complex_param_extraction(self): # cargo new [binary | lib] [using [rust | edition] <edition>] # (called | named) <name> p = Parser(start='start', end='end', transitions=[ Transition(fr='start', to='cargo', match='cargo'), Transition(fr='cargo', to='new', match='new'), Transition(fr='new', to='binlib', match='(binary|lib)'), Transition(fr='new', to='using', match='using'), Transition(fr='new', to='called', match='(called|named)'), Transition(fr='binlib', to='using', match='using'), Transition(fr='using', to='edition', match='(Rust|edition)'), Transition(fr='edition', to='called', match='\d{4}', param='edition'), Transition(fr='called', to='name', match='(called|named)'), Transition(fr='name', to='end', match='.*', param='name') ]) valid_inputs = [ 'cargo new called test', 'cargo new binary called test', 'cargo new lib called test', 'cargo new using 2018 called test', 'cargo new binary using 2018 named test', 'cargo new lib using Rust 2018 named test', 'cargo new lib using edition 2018 called test' ] for input_ in valid_inputs: args = p.parse(input_) edition = args.get('edition') assert edition is None or edition == '2018' assert 'name' in args and args['name'] == 'test'
def test_complex_param_extraction(self): # cargo new [binary | lib] [using [rust | edition] <edition>] # (called | named) <name> p = Parser(start='start', end='end', transitions=[ Transition(fr='start', to='cargo', match='cargo'), Transition(fr='cargo', to='new', match='new'), Transition(fr='new', to='binlib', match='(binary|lib)'), Transition(fr='new', to='using', match='using'), Transition(fr='new', to='called', match='(called|named)'), Transition(fr='binlib', to='using', match='using'), Transition(fr='using', to='edition', match='(Rust|edition)'), Transition(fr='edition', to='called', match='\d{4}', param='edition'), Transition(fr='called', to='name', match='(called|named)'), Transition(fr='name', to='end', match='.*', param='name') ]) invalid_inputs = [ 'cargo called test', 'cargo new test', 'cargo new lib test', 'cargo new 2018 called test', 'cargo new binary using 2018 named test', 'cargo new using 2018 test', ] for input_ in invalid_inputs: self.assertRaises(ParseError, p.parse, input_)