Exemplo n.º 1
0
 def test_make_parser_raises_error_on_invalid_generic_alias(
     self,
     generic_aliases: t.Iterable[t.Any],
 ) -> None:
     for hint in generic_aliases:
         with pytest.raises(TypeError):
             infer_parser(hint)
Exemplo n.º 2
0
class TestOptionalSequence:
    """Test infer_parser on optional sequence types."""
    @given(
        strategies.t_sequences(float).map(
            lambda s: infer_parser(t.Optional[s]), ),
        st.lists(st.floats(allow_nan=False).map(str)),
    )
    def test_parser_emits_sequence_of_emits(
        self,
        parser: Parser,
        tokens: t.List[str],
    ) -> None:
        expected = tuple(float(t) for t in tokens)
        result = parser(collections.deque(tokens))
        assert tuple(result.value) == expected

    @given(
        strategies.t_sequences(int).map(lambda s: infer_parser(t.Optional[s])),
        st.lists(st.text()).filter(
            lambda x: not x or not x[0].strip().isdecimal(), ),
    )
    def test_parser_emits_empty_sequence_instead_of_none(
        self,
        parser: Parser,
        tokens: t.List[str],
    ) -> None:
        result = parser(collections.deque(tokens))
        assert not result.empty
        assert result.value in ([], ())
Exemplo n.º 3
0
 def test_make_parser_raises_error(self) -> None:
     hints = [
         tuple[...],  # type: ignore
         tuple[..., int],  # type: ignore
         tuple[int, float, ...],  # type: ignore
     ]
     for hint in hints:
         with pytest.raises(TypeError):
             infer_parser(hint)
Exemplo n.º 4
0
 def test_make_parser_raises_error_on_unsupported_types(self) -> None:
     hints = [
         (),
         ...,
         t.Any,
         t.Callable[[int], int],
     ]
     for hint in hints:
         with pytest.raises(TypeError):
             infer_parser(hint)
Exemplo n.º 5
0
 def test_nested_types(self) -> None:
     hints = [
         t.Dict[t.Tuple[str, int], t.Tuple[str, t.Tuple[int, float]]],
         t.List[int],
         t.Tuple[int, t.Dict[str, str]],
         t.Tuple[str, ...],
         t.Tuple[t.Tuple[t.Tuple[str, int]], t.List[int]],
     ]
     for hint in hints:
         infer_parser(hint)
     assert True
Exemplo n.º 6
0
 def test_nested_generic_aliases(self) -> None:
     hints = [
         dict[  # type: ignore
             tuple[str, int], tuple[str, tuple[int, float]]  # type: ignore
         ],
         list[int],  # type: ignore
         tuple[int, dict[str, str]],  # type: ignore
         tuple[str, ...],  # type: ignore
         tuple[tuple[tuple[str, int]], list[int]],  # type: ignore
     ]
     for hint in hints:
         infer_parser(hint)
     assert True
Exemplo n.º 7
0
def test_make_parser_for_optional(
    tokens: t.List[str],
    expected: t.Optional[float],
) -> None:
    """Test infer_parser(Optional[...]).

    It should return None only after it has tried using the other types.
    """
    parse = infer_parser(t.Union[float, None])
    assert parse(collections.deque(tokens)).value == expected

    parse = infer_parser(t.Union[None, float])
    assert parse(collections.deque(tokens)).value == expected
Exemplo n.º 8
0
def test_make_parser_for_bool() -> None:
    """Test infer_parser(bool)."""
    parse = infer_parser(bool)
    truthy = (
        ["1"],
        ["t"],
        ["true"],
        ["y"],
        ["yes"],
    )
    falsy = (
        ["0"],
        ["f"],
        ["false"],
        ["n"],
        ["no"],
    )
    invalid: t.Tuple[t.List[str], ...] = (
        [],
        [""],
        [" false "],
        [" t.r.u.e."],
    )

    for tokens in truthy:
        assert parse(collections.deque(tokens)).value is True
    for tokens in falsy:
        assert parse(collections.deque(tokens)).value is False
    for tokens in invalid:
        with pytest.raises(CantParse):
            parse(collections.deque(tokens))
Exemplo n.º 9
0
def test_make_parser_for_union_order() -> None:
    """Make sure type hint arguments are checked in order.

    Note: t.Union[bool, int] becomes int in python 3.6.
    """
    parse = infer_parser(t.Union[bool, float])
    zero = parse(collections.deque(["0"]))
    assert zero.value is False
Exemplo n.º 10
0
def test_make_parser_for_class() -> None:
    """Test infer_parser on custom classes."""
    class Err:  # pylint: disable=too-few-public-methods
        """Invalid parser."""

    parse = infer_parser(Err)
    with pytest.raises(CantParse):
        parse(collections.deque(["hello"]))

    class Ok:  # pylint: disable=too-few-public-methods
        """Valid parser."""
        def __init__(self, arg: str):
            self.arg = arg

    parse = infer_parser(Ok)
    result = parse(collections.deque(["hello"])).value
    assert isinstance(result, Ok)
    assert result.arg == "hello"
Exemplo n.º 11
0
def test_make_parser_for_union(
    tokens: t.List[str],
    expected: t.Union[float, bool],
) -> None:
    """Test infer_parser(Union[...]).

    Order of type parameters matters.
    """
    parse = infer_parser(t.Union[float, bool])
    assert parse(collections.deque(tokens)).value == expected
Exemplo n.º 12
0
 def test_parser_with_sequence_inside(
     self,
     nested: t.Any,
     tokens: t.List[str],
 ) -> None:
     """Only the first type arg ever gets used."""
     parser = infer_parser(t.List[nested])  # type: ignore
     value = parser(collections.deque(tokens)).value
     assert len(value) == 1
     assert list(value[0]) == [int(t) for t in tokens]
Exemplo n.º 13
0
def test_empty_tuple(hint: t.Any, tokens: t.List[str]) -> None:
    """Parser should emit () without modifying the input."""
    parser = infer_parser(hint)
    deque = collections.deque(tokens)
    before = list(deque)
    result = parser(deque)
    after = list(deque)

    assert before == after
    assert not result.empty
    assert result.value == ()
Exemplo n.º 14
0
def test_make_parser_for_optional_fixed_length_tuple() -> None:
    """Parser should try to parse tuple or return None."""
    parse = infer_parser(t.Optional[t.Tuple[int, int]])

    cases = [
        (["1", "2", "3"], (1, 2)),
        (["1", "2"], (1, 2)),
        (["1"], None),
    ]
    for tokens, expected in cases:
        assert parse(collections.deque(tokens)).value == expected
Exemplo n.º 15
0
class TestList:
    """Test infer_parser(list[int])."""
    @given(
        strategies.t_lists(int).map(infer_parser),
        st.lists(st.integers().map(str)),
        st.lists(st.text()).filter(
            lambda x: not x or not x[0].strip().isdecimal(), ),
    )
    def test_parser_emits_valid_prefix(
        self,
        parser: Parser,
        tokens: t.List[str],
        trail: t.List[str],
    ) -> None:
        deque = collections.deque(tokens + trail)
        result = parser(deque)

        assert not result.empty
        assert result.value == [int(t) for t in tokens]
        assert tuple(deque) == tuple(trail)

    @given(
        strategies.t_lists(int).map(infer_parser),
        st.lists(st.text(st.characters(blacklist_categories=["Nd"]))),
    )
    @example(infer_parser(t.List[int]), [])
    @example(infer_parser(t.List[int]), [""])
    def test_parser_does_not_mutate_invalid_input(
        self,
        parser: Parser,
        tokens: t.List[str],
    ) -> None:
        deque = collections.deque(tokens)
        before = tuple(deque)
        parser(deque)
        after = tuple(deque)
        assert before == after
Exemplo n.º 16
0
def test_make_parser_for_dict_with_variable_length_key() -> None:
    """Parser should split keys and values correctly."""
    parse = infer_parser(t.Dict[t.Tuple[int, ...], str])
    cases: t.Any = [
        ([], {}),
        (["a", "b"], {
            (): "b"
        }),
        (["1", "2", "a", "b"], {
            (1, 2): "a",
            (): "b"
        }),
    ]
    for tokens, expected in cases:
        assert parse(collections.deque(tokens)).value == expected
Exemplo n.º 17
0
 def test_parser_on_invalid_int_literals(self, integer: int) -> None:
     literal = getattr(t, "Literal")  # pylint: disable=no-member
     parser = infer_parser(literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
     with pytest.raises(CantParse):
         parser(collections.deque([str(integer)]))
Exemplo n.º 18
0
 def test_parser_on_valid_int_literals(self, integer: int) -> None:
     literal = getattr(t, "Literal")  # pylint: disable=no-member
     parser = infer_parser(literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
     result = parser(collections.deque([str(integer)]))
     assert result.value == integer
Exemplo n.º 19
0
 def parser(self) -> Parser:
     return infer_parser(None)
Exemplo n.º 20
0
def test_make_parser_for_union_invalid_parse(tokens: t.List[str]) -> None:
    """Test infer_parser(Union[...]) on invalid inputs."""
    parse = infer_parser(t.Union[float, bool])
    with pytest.raises(CantParse):
        parse(collections.deque(tokens))
Exemplo n.º 21
0
def test_make_parser_for_annotated(args: t.Any) -> None:
    """Test infer_parser on Annotated types."""
    annotated = getattr(t, "Annotated")
    assert infer_parser(annotated[args]) == infer_parser(args[0])
Exemplo n.º 22
0
def test_make_parser_for_final() -> None:
    """Test make parser on Final types."""
    final = getattr(t, "Final")  # pylint: disable=no-member
    assert infer_parser(final[int]) == infer_parser(int)
Exemplo n.º 23
0
def test_make_parser_for_type(typ: type) -> None:
    """Test infer_parser on Type[...]."""
    assert infer_parser(t.Type[typ]) == infer_parser(typ)
Exemplo n.º 24
0
 def test_make_parser_for_nested_tuple(self) -> None:
     """Parser should parse inner tuple correctly."""
     parser = infer_parser(t.Tuple[t.Tuple[int, float], ...])
     result = parser(collections.deque(["1", "2", "3", "4"]))
     assert result.value == ((1, 2.0), (3, 4.0))
     assert parser(collections.deque(["1", "2", "3"])).value == ((1, 2.0), )
Exemplo n.º 25
0
def test_make_parser_for_float(tokens: t.List[str], expected: float) -> None:
    """Test infer_parser(float)."""
    parse = infer_parser(float)
    assert parse(collections.deque(tokens)).value == expected
Exemplo n.º 26
0
def test_make_parser_for_float_invalid_parse(tokens: t.List[str]) -> None:
    """Test infer_parser(float) parser on invalid inputs."""
    parse = infer_parser(float)
    with pytest.raises(CantParse):
        parse(collections.deque(tokens))
Exemplo n.º 27
0
def test_make_parser_for_str_invalid_parse() -> None:
    """Test infer_parser(str)."""
    parse = infer_parser(str)
    with pytest.raises(CantParse):
        parse(collections.deque([]))