def test_bounds_propagate_through_intersections(): x = rd.star(rd.char(b'\0\1')) y = rd.star(rd.char(b'\1\2')) assert isinstance( rd.bounded(rd.intersection(x, y), 3), rd.Intersection )
def test_derivatives_of_intersection(): x = rd.star(rd.char(b'\0\1')) y = rd.star(rd.literal(b'\0\1')) z = rd.intersection(x, y) d1 = rd.derivative(z, 0) d2 = rd.derivative(d1, 1) assert d2 is z
def test_merges_multiple_subtracts(): x = rd.star(rd.char(b'012')) y = rd.star(rd.char(b'0')) z = rd.star(rd.char(b'1')) t = rd.subtract(rd.subtract(x, y), z) assert t is rd.subtract(x, rd.union(y, z)) t = rd.subtract(x, rd.subtract(y, z)) assert t.nullable assert isinstance(t, rd.Union)
def test_bounds_propagate_through_subtraction(): x = rd.star(rd.char(b'\0\1')) y = rd.literal(b'\0\0\0\1') z = rd.subtract(x, y) b = rd.bounded(z, 10) assert isinstance(b, rd.Subtraction) assert isinstance(b.left, rd.Bounded)
def test_bounds_are_not_nested(): x = rd.bounded(rd.star(rd.char(0)), 7) y = rd.bounded(x, 5) assert x.bound == 7 assert y.bound == 5 assert isinstance(y.child, rd.Star)
def test_subtraction_from_epsilon_checks_nullability(): assert rd.subtract(rd.Epsilon, rd.char(0)) is rd.Epsilon assert rd.subtract(rd.Epsilon, rd.star(rd.char(0))) is rd.Empty
def test_raises_if_parameter_too_large(): reg = rd.star(rd.char(b'\0\1\2\3')) sim = Simulator(reg, 0) with pytest.raises(ValueError): next(sim.draw(0.5))
def test_non_empty_star_dfa(): accepting, _ = rd.build_dfa(rd.nonempty(rd.star(rd.char(0)))) assert accepting == [False, True]
def test_bounded_is_not_infinite(): assert not rd.is_infinite(rd.bounded(rd.star(rd.char(0)), 10 ** 6))
def test_union_of_infinite_and_finite_is_infinite(): assert rd.is_infinite(rd.union(rd.char(1), rd.star(rd.char(0))))
def test_valid_starts_of_subtraction(): x = rd.star(rd.char(b'\0\1')) y = rd.char(b'\1') z = rd.subtract(x, y) assert rd.valid_starts(z) == pset([0, 1])
def test_star_collapses_stars(): x = rd.star(rd.char(0)) assert rd.star(x) is x
def test_star_collapses_trivial_children(): assert rd.star(rd.Empty) is rd.Epsilon assert rd.star(rd.Epsilon) is rd.Epsilon
def test_bounds_propagate_through_unions(): assert isinstance( rd.bounded(rd.union(rd.star(rd.char(0)), rd.star(rd.char(1))), 1), rd.Union )
@given(regex()) def test_characters_in_same_class_produce_equivalent_expressions(re): assume(rd.has_matches(re)) classes = rd.character_classes(re) assume(any(len(cs) > 1 for cs in classes)) for cs in classes: if len(cs) > 1: derivs = [rd.derivative(re, c) for c in cs] for a in derivs: for b in derivs: assert rd.equivalent(a, b) @example(rd.star(rd.char(b'0'))) @example(rd.subtract(rd.star(rd.char(b'0')), rd.char(b'0'))) @given(regex()) def test_infinite_regex_have_more_than_one_solution(reg): assume(rd.is_infinite(reg)) x = rd.subtract(reg, rd.literal(rd.lexmin(reg))) assert rd.has_matches(x) @example(rd.concatenate(rd.star(rd.char(b'\0')), rd.char(b'\1'))) @example(rd.union(rd.char(b'\0'), rd.star(rd.literal(b'\0\0')))) @example(rd.star(rd.char(0))) @given(regex()) def test_decompilation(re): assume(rd.has_matches(re)) dfa = rd.build_dfa(re)
def test_derivatives_of_unions(): assert rd.derivative( rd.union(rd.star(rd.char(0)), rd.star(rd.char(1))), 0 ) is rd.star(rd.char(0))
def test_flattens_unions(): x = rd.star(rd.char(0)) y = rd.star(rd.char(1)) z = rd.star(rd.char(2)) assert rd.union(x, rd.union(y, z)) is rd.union(rd.union(x, z), y)
def test_flattens_intersections(): x = rd.star(rd.char(b'01')) y = rd.star(rd.char(b'02')) z = rd.star(rd.char(b'03')) assert rd.intersection(x, rd.intersection(y, z)) is \ rd.intersection(rd.intersection(x, z), y)
def test_lexmin_of_star_is_empty(): assert rd.lexmin(rd.star(rd.char(b'0'))) is b''
def test_epsilon_prunes_down_intersections(): assert rd.intersection(rd.Epsilon, rd.star(rd.char(0))) is rd.Epsilon assert rd.intersection(rd.Epsilon, rd.char(0)) is rd.Empty
def test_can_walk_graph_for_infintiy(): assert rd.is_infinite(rd.intersection( rd.star(rd.char(b'01')), rd.star(rd.char(b'12')) ))
def test_valid_starts_of_nullable_cat(): x = rd.concatenate(rd.star(rd.char(0)), rd.char(1)) assert rd.valid_starts(x) == pset([0, 1])
def test_complex_graphs_may_be_finite(): x = to_basic(rd.bounded( rd.union(rd.star(rd.char(0)), rd.star(rd.char(1))), 20)) assert not rd.is_infinite(x)
def test_rebalances_concatenation(): x = rd.char(0) y = rd.star(rd.char(1)) z = rd.char(2) assert rd.concatenate(x, rd.concatenate(y, z)) is \ rd.concatenate(rd.concatenate(x, y), z)
def test_two_phase_dfa(): re = rd.concatenate(rd.star(rd.char(0)), rd.star(rd.char(1))) accepting, transitions = rd.build_dfa(re) assert accepting == [True, True] assert transitions == [{0: 0, 1: 1}, {1: 1}]
import hypothesis.strategies as st import falbs.regex as rd from falbs import Simulator, compute_generating_functions, ParamTooLarge from hypothesis import given, assume, note, example, reject from tests.helpers import regex from sympy import series import pytest @given(regex()) def test_can_compute_a_generating_function(re): compute_generating_functions(*rd.build_dfa(re)) @example(rd.literal(b'\0\0'), 0, None, 0.01) @example(rd.star(rd.char(b'\0')), 0, None, 0.01) @example(rd.star(rd.char(b'\0')), 0, 1, 0.01) @example(rd.star(rd.char(b'\0')), 0, 0, 0.5) @given( regex(state_bound=10), st.integers(), st.none() | st.integers(0, 10), st.floats(0, 0.5), ) def test_can_simulate_accurately(regex, seed, max_size, param): assume(param > 0) assume(rd.has_matches(regex)) if max_size is not None: assume(rd.has_matches(rd.bounded(regex, max_size))) sim = Simulator(regex, seed) d = sim.draw(param, max_size=max_size)