aboutsummaryrefslogtreecommitdiff
path: root/sigsum/ascii_test.py
blob: 6dfe0250b1ae30aadd1fd61d1f8571377e69d871 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import io
import operator
from operator import methodcaller as M

from . import ascii


def test():
    pass


import pytest


@pytest.mark.parametrize(
    "txt, expected",
    [
        ("", {}),
        ("foo=bar", {"foo": ["bar"]}),
        ("foo=bar\nqux=42", {"foo": ["bar"], "qux": ["42"]}),
        ("foo=bar\nfoo=biz", {"foo": ["bar", "biz"]}),
        ("error=something went wrong", {"error": ["something went wrong"]}),
        ("error=a message with an = sign", {"error": ["a message with an = sign"]}),
    ],
)
def test_loads(txt, expected):
    assert ascii.loads(txt) == expected


@pytest.mark.parametrize(
    "txt, message",
    [
        ("foo", "Expecting '=' delimiter line 1"),
        ("foo=", "Expecting value after '=' line 1"),
    ],
)
def test_loads_error(txt, message):
    with pytest.raises(ascii.ASCIIDecodeError, match=message):
        ascii.loads(txt)


@pytest.mark.parametrize(
    "data, expected",
    [
        ({}, ""),
        ({"foo": ["bar"], "baz": ["biz"]}, "foo=bar\nbaz=biz\n"),
        ({"foo": ["bar", "baz"]}, "foo=bar\nfoo=baz\n"),
        ({"foo": [42]}, "foo=42\n"),
        ({"foo": [b"\xDE\xAD\xBE\xEF"]}, "foo=deadbeef\n"),
        ({"foo": "bar"}, "foo=bar\n"),
    ],
    ids=["empty", "simple", "list", "int", "bytes", "single-value-shortcut"],
)
def test_dumps(data, expected):
    assert ascii.dumps(data) == expected


def test_dumps_type_error():
    with pytest.raises(
        TypeError, match="Object of type object is not ASCII serializable"
    ):
        ascii.dumps({"foo": [object()]})


@pytest.mark.parametrize(
    "data, func, expected",
    [
        # Check that it behave like a Mapping[str, List[str]]
        ([("foo", "bar"), ("foo", "baz")], operator.itemgetter("foo"), ["bar", "baz"]),
        ([("foo", "bar"), ("foo", "baz")], len, 1),
        ([("foo", "bar"), ("foo", "baz")], lambda x: list(iter(x)), ["foo"]),
        # Check accessors
        ([("foo", "bar")], M("getone", "foo"), "bar"),
        ([("foo", "42")], M("getint", "foo"), 42),
        ([("foo", "deadbeef")], M("getbytes", "foo"), b"\xDE\xAD\xBE\xEF"),
        ([("foo", "42"), ("foo", "0")], M("getint", "foo", True), [42, 0]),
        (
            [("foo", "dead"), ("foo", "beef")],
            M("getbytes", "foo", True),
            [b"\xDE\xAD", b"\xBE\xEF"],
        ),
    ],
)
def test_asciivalue_getters(data, func, expected):
    kv = ascii.ASCIIValue(data)
    assert func(kv) == expected


@pytest.mark.parametrize(
    "data, func, error",
    [
        # missing key
        ([], M("getone", "foo"), KeyError),
        ([], M("getint", "foo"), KeyError),
        ([], M("getbytes", "foo"), KeyError),
        # too many values
        ([("foo", "bar"), ("foo", "baz")], M("getone", "foo"), ValueError),
        ([("foo", "42"), ("foo", "0")], M("getint", "foo"), ValueError),
        ([("foo", "dead"), ("foo", "beef")], M("getbytes", "foo"), ValueError),
        # strconv errors
        ([("foo", "xx")], M("getint", "foo"), ValueError),
        ([("foo", "xx")], M("getbytes", "foo"), ValueError),
    ],
)
def test_asciivalue_getters_errorrs(data, func, error):
    kv = ascii.ASCIIValue(data)
    with pytest.raises(error):
        func(kv)


def test_asciivalue_repr():
    v = ascii.ASCIIValue([("foo", "bar"), ("foo", "baz"), ("qux", "quux")])
    assert repr(v) == "ASCIIValue([('foo', 'bar'), ('foo', 'baz'), ('qux', 'quux')])"


def test_asciivalue_eq():
    v = ascii.ASCIIValue([("foo", "bar"), ("foo", "baz"), ("qux", "quux")])
    assert v == ascii.ASCIIValue([("foo", "bar"), ("foo", "baz"), ("qux", "quux")])
    assert v == {"foo": ["bar", "baz"], "qux": ["quux"]}