def test_end_no_stack(): with pytest.raises(RuntimeError): SuperExpressive().end()
def test_clashing_start_end(): with pytest.raises(ValueError): (SuperExpressive( check_simple_start_and_end=True).end_of_input.subexpression( START_END, ignore_start_and_end=False))
def test_name_collision_with_namespace(): with pytest.raises(ValueError): (SuperExpressive().named_capture('yolomodule').at_least( 3).digit.end().subexpression(NAMED_CAPTURE, namespace='yolo').range('0', '9'))
def test_simple(): assert str(SuperExpressive().start_of_input.at_least( 3).digit.subexpression(SIMPLE).range( '0', '9').end_of_input) == r'^\d{3,}hello.world[0-9]$'
def test_flags_merge(): assert (SuperExpressive().line_by_line.start_of_input.at_least( 3).digit.subexpression(FLAGS, ignore_flags=False).range( '0', '9').end_of_input.compile()).flags == ( FLAGS.compile().flags | SuperExpressive().line_by_line.compile().flags)
def test_backreference(): assert str(SuperExpressive().capture.string('hello ').word.char( '!').end().backreference(1)) == r'(hello \w!)\1'
def test_deeply_nested(): assert str( SuperExpressive().capture.at_least(3).digit.end().subexpression( FIRST_LAYER).backreference(1).range('0', '9') ) == r'(\d{3,})outer begin(?P<innerSubExpression>(?:.{2})?)outer end\1[0-9]'
def test_hex_char() -> None: for n in range(0x00, 0xFF + 1): code = hex(n)[2:].rjust(2, '0') assert str(SuperExpressive().hex_char(code)) == f'\\x{code}'
def test_double_unicode_char(n: int) -> None: code = hex(n)[2:].rjust(8, '0') assert str(SuperExpressive().unicode_char(code)) == f'\\U{code}'
def test_char_more_than_one_char() -> None: with pytest.raises(ValueError): SuperExpressive().char('hello')
def test_ascii_backspace() -> None: with pytest.raises(RuntimeError): _ = SuperExpressive().ascii_backspace assert str(SuperExpressive().any_of.ascii_backspace.end()) == r'(?:\b)'
def test_empty() -> None: assert str(SuperExpressive()) == ''
def test_assert_not_ahead(): assert str(SuperExpressive().assert_not_ahead.range('a', 'f').end().range( '0', '9')) == r'(?![a-f])[0-9]'
def test_assert_ahead(): assert str(SuperExpressive().assert_ahead.range('a', 'f').end().range( 'a', 'z')) == r'(?=[a-f])[a-z]'
def test_named_backreference(): assert str(SuperExpressive().named_capture('this_is_the_name').string( 'hello ').word.char('!').end().named_backreference('this_is_the_name') ) == r'(?P<this_is_the_name>hello \w!)\g<this_is_the_name>'
def test_double_unicode_char(character: str) -> None: name = NAMED_UNICODE[character] assert str(SuperExpressive().unicode_char(name)) == f'\\N{{{name}}}'
def test_missing_named_backreference(): with pytest.raises(ValueError): SuperExpressive().named_backreference('not_here')
def test_flags(se: SuperExpressive, flags: int) -> None: assert se.compile().flags == flags
"""Test subexpressions.""" import pytest from superexpressive import SuperExpressive SIMPLE = (SuperExpressive().string('hello').any_char.string('world')) FLAGS = (SuperExpressive().unicode.case_insensitive.string( 'hello').any_char.string('world')) START_END = (SuperExpressive().start_of_input.string('hello').any_char.string( 'world').end_of_input) NAMED_CAPTURE = (SuperExpressive().named_capture('module').exactly( 2).any_char.end().named_backreference('module')) INDEXED_BACKREFERENCE = ( SuperExpressive().capture.exactly(2).any_char.end().backreference(1)) SECOND_LAYER = SuperExpressive().exactly(2).any_char FIRST_LAYER = ( SuperExpressive().string('outer begin').named_capture('innerSubExpression') .optional.subexpression(SECOND_LAYER).end().string('outer end')) def test_wrong_input_type(): with pytest.raises(Exception): SuperExpressive().subexpression('nope')
def test_any_of_basic(): assert str(SuperExpressive().any_of.string('hello').digit.word.char( '.').char('#').end()) == r'(?:hello|\d|\w|[\.#])'
def test_wrong_input_type(): with pytest.raises(Exception): SuperExpressive().subexpression('nope')
def test_any_of_range_fusion(): assert str(SuperExpressive().any_of.range('a', 'z').range('A', 'Z').range( '0', '9').char('.').char('#').end()) == r'[a-zA-Z0-9\.#]'
def test_simple_quantified(): assert str(SuperExpressive().start_of_input.at_least( 3).digit.one_or_more.subexpression(SIMPLE).range( '0', '9').end_of_input) == r'^\d{3,}(?:hello.world)+[0-9]$'
def test_any_of_range_fusion_with_other_choices(): assert str(SuperExpressive().any_of.range('a', 'z').range('A', 'Z').range( '0', '9').char('.').char('#').string( 'XXX').end()) == r'(?:XXX|[a-zA-Z0-9\.#])'
def test_start_end(): assert str( SuperExpressive( check_simple_start_and_end=True).at_least(3).digit.subexpression( START_END, ignore_start_and_end=False).range( '0', '9')) == r'\d{3,}^hello.world$[0-9]'
def test_capture(): assert str(SuperExpressive().capture.string('hello ').word.char( '!').end()) == r'(hello \w!)'
def test_namespacing(): assert str(SuperExpressive().at_least(3).digit.subexpression( NAMED_CAPTURE, namespace='yolo').range( '0', '9')) == r'\d{3,}(?P<yolomodule>.{2})\g<yolomodule>[0-9]'
def test_named_capture_duplicate_name(): with pytest.raises(ValueError): (SuperExpressive().named_capture('hello world').string( 'hello ').word.char('!').end().named_capture('hello world').string( 'hello ').word.char('!').end())
def test_indexed_backreferencing(): assert str(SuperExpressive().capture.at_least(3).digit.end().subexpression( INDEXED_BACKREFERENCE).backreference(1).range( '0', '9')) == r'(\d{3,})(.{2})\2\1[0-9]'
def test_group(): assert str(SuperExpressive().group.string('hello ').word.char( '!').end()) == r'(?:hello \w!)'