def test_fsm_supports_fluent_inplace_operations(self, scanner_class, parse_scanner): a = pire.Fsm().Append("a").AppendDot() b = pire.Fsm() b.Append("b") d = pire.Fsm().Append("d") d *= 3 c = pire.Lexer("c").Parse() fsm = a.Iterate() fsm += b.AppendAnything() fsm |= d fsm &= c.PrependAnything().Complement() expected_scanner = parse_scanner("((a.)*(b.*)|(d{3}))&~(.*c)", "a") check_equivalence(expected_scanner, scanner_class(fsm), [ "ddd", "dddc", "a-b--c", "a-a-b--", "bdddc", "bddd", "", "b", "bc", "c", ])
def test_fsm_is_copy_constructible(self): fsm = pire.Fsm().Append("ab") fsm_copy = pire.Fsm(fsm) assert fsm_copy is not fsm check_equivalence( fsm.Compile(), fsm_copy.Compile(), ["", "a", "ab", "ab-", "-"], ) fsm.Append("c") assert not fsm_copy.Compile().Matches("abc")
def test_counting_scanner_raises_when_constructed_without_second_fsm(self): fsm = pire.Fsm() with pytest.raises(ValueError): pire.CountingScanner(fsm) with pytest.raises(ValueError): pire.CountingScanner(pattern=fsm) with pytest.raises(ValueError): pire.CountingScanner(sep=fsm)
def test_fsm_supports_appending_several_strings(self, scanner_class): fsm = pire.Fsm().Append("-") fsm.AppendStrings(["abc", "de"]) check_scanner( scanner_class(fsm), accepts=["-abc", "-de"], rejects=["-", "abc", ""], )
def test_fsm_supports_appending_generated_strings(self, scanner_class): import itertools fsm = pire.Fsm().Append("-") fsm.AppendStrings(itertools.imap(str, ["abc", "de"])) check_scanner( scanner_class(fsm), accepts=["-abc", "-de"], rejects=["-", "abc", ""], )
def test_fsm_raises_when_appending_invalid_special(self): invalid_chars = [ pire.MaxCharUnaligned, pire.MaxCharUnaligned + 2, ] fsm = pire.Fsm() for invalid_char in invalid_chars: with pytest.raises(ValueError): fsm.AppendSpecial(invalid_char) for not_convertible in [-1, -42, 2**200, 2**30]: with pytest.raises(OverflowError): fsm.AppendSpecial(not_convertible)
def test_fsm_supports_appending_special(self, scanner_class): fsm = pire.Fsm() fsm.AppendSpecial(pire.BeginMark) fsm.Append('a') fsm.AppendSpecial(pire.EndMark) scanner = scanner_class(fsm) state = scanner.InitState() check_state(state.Begin(), final=False, dead=False) check_state(state.Run('a'), final=False, dead=False) check_state(state.Step(pire.EndMark), final=True)
def test_fsm_compiles_to_scanner_of_choice(self, scanner_class): assert scanner_class == type(pire.Fsm().Compile(scanner_class))
def test_default_fsm_compiles_to_default_scanner(self): scanner = pire.Fsm().Compile() assert pire.Scanner == type(scanner)
def test_fsm_is_default_constructible(self): f = pire.Fsm() assert 1 == f.Size()
def test_counting_scanner_is_default_constructible(self): fsm = pire.Fsm() pire.CountingScanner()
def test_fsm_raises_when_one_of_appended_strings_is_empty(self): fsm = pire.Fsm() for invalid_strings in [[""], ["nonempty", ""]]: with pytest.raises(ValueError): fsm.AppendStrings(invalid_strings)