Beispiel #1
0
def test_trailing_escape_value_list():
    cl1 = ContentLine.parse("TEST:this is,a list \\, with a\\\\,trailing escape\\")
    with pytest.raises(ValueError) as excinfo:
        list(TextConv.split_value_list(cl1.value))
    assert "not end with an escape sequence" in str(excinfo.value)

    cl2 = ContentLine.parse("TEST:this is,a list \\, with a\\\\,trailing escape")
    assert list(TextConv.split_value_list(cl2.value)) == \
           ["this is", "a list \\, with a\\\\", "trailing escape"]
    assert [TextConv.parse(v) for v in TextConv.split_value_list(cl2.value)] == \
           ["this is", "a list , with a\\", "trailing escape"]
Beispiel #2
0
def test_contentline_funcs():
    cl = ContentLine("TEST", {"PARAM": ["VAL"]}, "VALUE")
    assert cl["PARAM"] == ["VAL"]
    cl["PARAM2"] = ["VALA", "VALB"]
    assert cl.params == {"PARAM": ["VAL"], "PARAM2": ["VALA", "VALB"]}
    cl_clone = cl.clone()
    assert cl == cl_clone and cl is not cl_clone
    assert cl.params == cl_clone.params and cl.params is not cl_clone.params
    assert cl.params["PARAM2"] == cl_clone.params["PARAM2"] and cl.params["PARAM2"] is not cl_clone.params["PARAM2"]
    cl_clone["PARAM2"].append("VALC")
    assert cl != cl_clone
    assert str(cl) == "TEST{'PARAM': ['VAL'], 'PARAM2': ['VALA', 'VALB']}='VALUE'"
    assert str(cl_clone) == "TEST{'PARAM': ['VAL'], 'PARAM2': ['VALA', 'VALB', 'VALC']}='VALUE'"
Beispiel #3
0
def test_value_characters():
    chars = "abcABC0123456789"  "-=_+!$%&*()[]{}<>'@#~/?|`¬€¨ÄÄää´ÁÁááßæÆ \t\\n😜🇪🇺👩🏾‍💻👨🏻‍👩🏻‍👧🏻‍👦🏻xyzXYZ"
    special_chars = ";:,\"^"
    inp = "TEST;P1={chars};P2={chars},{chars},\"{chars}\",{chars}:{chars}:{chars}{special}".format(
        chars=chars, special=special_chars)
    out = ContentLine("TEST", {"P1": [chars], "P2": [chars, chars, QuotedParamValue(chars), chars]},
                      chars + ":" + chars + special_chars)
    par = ContentLine.parse(inp)
    assert par == out
    ser = out.serialize()
    assert inp == ser
    par_ser = par.serialize()
    assert inp == par_ser
    assert string_to_container(inp) == [out]
Beispiel #4
0
def test_any_text_value_recode(value):
    esc = TextConv.serialize(value)
    assert TextConv.parse(esc) == value
    cl = ContentLine("TEST", value=esc)
    assert ContentLine.parse(cl.serialize()) == cl
    assert string_to_container(cl.serialize()) == [cl]
    vals = [esc, esc, "test", esc]
    cl2 = ContentLine("TEST", value=TextConv.join_value_list(vals))
    assert list(TextConv.split_value_list(cl2.value)) == vals
    assert ContentLine.parse(cl.serialize()) == cl
    assert string_to_container(cl.serialize()) == [cl]
Beispiel #5
0
def test_container_parse_error():
    pytest.raises(ParseError, string_to_container, "BEGIN:TEST")
    assert string_to_container("END:TEST") == [ContentLine(name="END", value="TEST")]
    pytest.raises(ParseError, string_to_container, "BEGIN:TEST1\nEND:TEST2")
    pytest.raises(ParseError, string_to_container, "BEGIN:TEST1\nEND:TEST2\nEND:TEST1")
    assert string_to_container("BEGIN:TEST1\nEND:TEST1\nEND:TEST1") == [Container("TEST1"), ContentLine(name="END", value="TEST1")]
    pytest.raises(ParseError, string_to_container, "BEGIN:TEST1\nBEGIN:TEST1\nEND:TEST1")
Beispiel #6
0
def test_example_text_recode(inp_esc, out_uesc):
    par_esc = ContentLine.parse(inp_esc)
    par_uesc = attr.evolve(par_esc, value=TextConv.parse(par_esc.value))
    out_esc = attr.evolve(out_uesc, value=TextConv.serialize(out_uesc.value))
    assert par_uesc == out_uesc
    ser_esc = out_esc.serialize()
    assert inp_esc == ser_esc
    assert string_to_container(inp_esc) == [par_esc]
Beispiel #7
0
def test_container_nested():
    inp = """BEGIN:TEST1
VAL1:The-Val
BEGIN:TEST2
VAL2:The-Val
BEGIN:TEST3
VAL3:The-Val
END:TEST3
END:TEST2
VAL4:The-Val
BEGIN:TEST2
VAL5:The-Val
END:TEST2
BEGIN:TEST2
VAL5:The-Val
END:TEST2
VAL6:The-Val
END:TEST1"""
    out = Container('TEST1', [
        ContentLine(name='VAL1', params={}, value='The-Val'),
        Container('TEST2', [
            ContentLine(name='VAL2', params={}, value='The-Val'),
            Container('TEST3', [
                ContentLine(name='VAL3', params={}, value='The-Val')
            ])
        ]),
        ContentLine(name='VAL4', params={}, value='The-Val'),
        Container('TEST2', [
            ContentLine(name='VAL5', params={}, value='The-Val')]),
        Container('TEST2', [
            ContentLine(name='VAL5', params={}, value='The-Val')]),
        ContentLine(name='VAL6', params={}, value='The-Val')])

    assert string_to_container(inp) == [out]
    assert out.serialize() == inp.replace("\n", "\r\n")
Beispiel #8
0
def test_param_quoting():
    inp = 'TEST;P1="A";P2=B;P3=C,"D",E,"F":"VAL"'
    out = ContentLine("TEST", {
        "P1": [QuotedParamValue("A")],
        "P2": ["B"],
        "P3": ["C", QuotedParamValue("D"), "E", QuotedParamValue("F")],
    }, '"VAL"')
    par = ContentLine.parse(inp)
    assert par == out
    ser = out.serialize()
    assert inp == ser
    par_ser = par.serialize()
    assert inp == par_ser
    assert string_to_container(inp) == [out]

    for param in out.params.keys():
        for o_val, p_val in zip(out[param], par[param]):
            assert type(o_val) == type(p_val)
Beispiel #9
0
def test_example_recode(inp, out):
    par = ContentLine.parse(inp)
    assert par == out
    ser = out.serialize()
    if inp[0].isupper():
        assert inp == ser
    else:
        assert inp.upper() == ser.upper()
    par_ser = par.serialize()
    if inp[0].isupper():
        assert inp == par_ser
    else:
        assert inp.upper() == par_ser.upper()
    assert string_to_container(inp) == [out]
Beispiel #10
0
 def serialize(self, component: "Component", output: Container,
               context: ContextDict):
     if self.is_multi_value:
         self.__serialize_multi(component, output, context)
     else:
         value = self.get_value(component)
         if value:
             params = copy_extra_params(
                 cast(ExtraParams, self.get_extra_params(component)))
             converter = self.__find_value_converter(params, value)
             serialized = converter.serialize(value, params, context)
             output.append(
                 ContentLine(name=self.ics_name,
                             params=params,
                             value=serialized))
Beispiel #11
0
    def __serialize_multi(self, component: "Component", output: "Container",
                          context: ContextDict):
        extra_params = cast(List[ExtraParams],
                            self.get_extra_params(component))
        values = self.get_value_list(component)
        if len(extra_params) != len(values):
            raise ValueError(
                "length of extra params doesn't match length of parameters"
                " for attribute %s of %r" % (self.attribute.name, component))

        merge_next = False
        current_params = None
        current_values = []

        for value, params in zip(values, extra_params):
            merge_next = False
            params = copy_extra_params(params)
            if params.pop("__merge_next", None) == ["TRUE"]:
                merge_next = True
            converter = self.__find_value_converter(params, value)
            serialized = converter.serialize(
                value, params, context)  # might modify params and context

            if current_params is not None:
                if current_params != params:
                    raise ValueError()
            else:
                current_params = params

            current_values.append(serialized)

            if not merge_next:
                cl = ContentLine(
                    name=self.ics_name,
                    params=params,
                    value=converter.join_value_list(current_values))
                output.append(cl)
                current_params = None
                current_values = []

        if merge_next:
            raise ValueError(
                "last value in value list may not have merge_next set")
Beispiel #12
0
def test_unfold():
    val1 = "DESCRIPTION:This is a long description that exists on a long line."
    val2 = "DESCRIPTION:This is a lo\n ng description\n  that exists on a long line."
    assert "".join(unfold_lines(val2.splitlines())) == val1
    assert string_to_container(val1) == string_to_container(val2) == [ContentLine.parse(val1)]
    pytest.raises(ValueError, ContentLine.parse, val2)
Beispiel #13
0
def test_container():
    inp = """BEGIN:TEST
VAL1:The-Val
VAL2;PARAM1=P1;PARAM2=P2A,P2B;PARAM3="P3:A","P3:B,C":The-Val2
END:TEST"""
    out = Container('TEST', [
        ContentLine(name='VAL1', params={}, value='The-Val'),
        ContentLine(name='VAL2', params={'PARAM1': ['P1'], 'PARAM2': ['P2A', 'P2B'], 'PARAM3': ['P3:A', 'P3:B,C']}, value='The-Val2')])

    assert string_to_container(inp) == [out]
    assert out.serialize() == inp.replace("\n", "\r\n")
    assert str(out) == "TEST[VAL1='The-Val', VAL2{'PARAM1': ['P1'], 'PARAM2': ['P2A', 'P2B'], 'PARAM3': ['P3:A', 'P3:B,C']}='The-Val2']"
    assert repr(out) == "Container('TEST', [ContentLine(name='VAL1', params={}, value='The-Val'), ContentLine(name='VAL2', params={'PARAM1': ['P1'], 'PARAM2': ['P2A', 'P2B'], 'PARAM3': ['P3:A', 'P3:B,C']}, value='The-Val2')])"

    out_shallow = out.clone(deep=False)
    out_deep = out.clone(deep=True)
    assert out == out_shallow == out_deep
    assert all(a == b for a, b in zip(out, out_shallow))
    assert all(a == b for a, b in zip(out, out_deep))
    assert all(a is b for a, b in zip(out, out_shallow))
    assert all(a is not b for a, b in zip(out, out_deep))
    out_deep.append(ContentLine("LAST"))
    assert out != out_deep
    out[0].params["NEW"] = "SOMETHING"
    assert out == out_shallow
    out_shallow.name = "DIFFERENT"
    assert out != out_shallow

    with pytest.raises(TypeError):
        out_shallow[0] = ['CONTENT:Line']
    with pytest.raises(TypeError):
        out_shallow[:] = ['CONTENT:Line']
    pytest.raises(TypeError, out_shallow.append, 'CONTENT:Line')
    pytest.raises(TypeError, out_shallow.append, ['CONTENT:Line'])
    pytest.raises(TypeError, out_shallow.extend, ['CONTENT:Line'])
    out_shallow[:] = [out[0]]
    assert out_shallow == Container("DIFFERENT", [out[0]])
    out_shallow[:] = []
    assert out_shallow == Container("DIFFERENT")
    out_shallow.append(ContentLine("CL1"))
    out_shallow.extend([ContentLine("CL3")])
    out_shallow.insert(1, ContentLine("CL2"))
    out_shallow += [ContentLine("CL4")]
    assert out_shallow[1:3] == Container("DIFFERENT", [ContentLine("CL2"), ContentLine("CL3")])
    assert out_shallow == Container("DIFFERENT", [ContentLine("CL1"), ContentLine("CL2"), ContentLine("CL3"), ContentLine("CL4")])

    with pytest.warns(UserWarning, match="not all-uppercase"):
        assert string_to_container("BEGIN:test\nEND:TeSt") == [Container("TEST", [])]
Beispiel #14
0
def test_any_name_value_recode(name, value):
    raw = "%s:%s" % (name, value)
    assert ContentLine.parse(raw).serialize() == raw
    cl = ContentLine(name, value=value)
    assert ContentLine.parse(cl.serialize()) == cl
    assert string_to_container(raw) == [cl]
Beispiel #15
0
def test_trailing_escape_param():
    with pytest.raises(ValueError) as excinfo:
        ContentLine.parse("TEST;PARAM=this ^^ is a ^'param^',with a ^trailing escape^:value")
    assert "not end with an escape sequence" in str(excinfo.value)
    assert ContentLine.parse("TEST;PARAM=this ^^ is a ^'param^',with a ^trailing escape:value").params["PARAM"] == \
           ["this ^ is a \"param\"", "with a ^trailing escape"]
Beispiel #16
0
import re

import pytest
from hypothesis import assume, given, example
from hypothesis.strategies import characters, text

from ics.grammar import Container, ContentLine, ParseError, QuotedParamValue, escape_param, string_to_container, unfold_lines

CONTROL = [chr(i) for i in range(ord(" ")) if i != ord("\t")] + [chr(0x7F)]
NAME = text(alphabet=(characters(whitelist_categories=["Lu"], whitelist_characters=["-"], max_codepoint=128)), min_size=1)
VALUE = text(characters(blacklist_categories=["Cs"], blacklist_characters=CONTROL))


@pytest.mark.parametrize("inp, out", [
    ('HAHA:', ContentLine(name='HAHA', params={}, value='')),
    ('HAHA:hoho', ContentLine(name='HAHA', params={}, value='hoho')),
    ('HAHA:hoho:hihi', ContentLine(name='HAHA', params={}, value='hoho:hihi')),
    (
            'HAHA;hoho=1:hoho',
            ContentLine(name='HAHA', params={'hoho': ['1']}, value='hoho')
    ), (
            'RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU',
            ContentLine(name='RRULE', params={}, value='FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU')
    ), (
            'SUMMARY:dfqsdfjqkshflqsjdfhqs fqsfhlqs dfkqsldfkqsdfqsfqsfqsfs',
            ContentLine(name='SUMMARY', params={}, value='dfqsdfjqkshflqsjdfhqs fqsfhlqs dfkqsldfkqsdfqsfqsfqsfs')
    ), (
            'DTSTART;TZID=Europe/Brussels:20131029T103000',
            ContentLine(name='DTSTART', params={'TZID': ['Europe/Brussels']}, value='20131029T103000')
    ), (
            'haha;p2=v2;p1=v1:',
Beispiel #17
0
def test_any_param_value_recode(param, value):
    raw = "TEST;%s=%s:VALUE" % (param, quote_escape_param(value))
    assert ContentLine.parse(raw).serialize() == raw
    cl = ContentLine("TEST", {param: [value]}, "VALUE")
    assert ContentLine.parse(cl.serialize()) == cl
    assert string_to_container(raw) == [cl]
Beispiel #18
0
import attr
import pytest
from hypothesis import given

from ics.grammar import ContentLine, string_to_container
from ics.valuetype.text import TextConverter
# Text may be comma-separated multi-value but is never quoted, with the characters [\\;,\n] escaped
from tests.grammar import VALUE

TextConv: TextConverter = TextConverter.INST


@pytest.mark.parametrize("inp_esc, out_uesc", [
    (
            "SUMMARY:Project XYZ Final Review\\nConference Room - 3B\\nCome Prepared.",
            ContentLine("SUMMARY", value="Project XYZ Final Review\nConference Room - 3B\nCome Prepared.")
    ),
    (
            "DESCRIPTION;ALTREP=\"cid:[email protected]\":The Fall'98 Wild Wizards Conference - - Las Vegas\\, NV\\, USA",
            ContentLine("DESCRIPTION", {"ALTREP": ["cid:[email protected]"]}, value="The Fall'98 Wild Wizards Conference - - Las Vegas, NV, USA")
    ),
    (
            "TEST:abc\\r\\n\\,\\;:\"\t=xyz",
            ContentLine("TEST", value="abc\r\n,;:\"\t=xyz")
    ),
])
def test_example_text_recode(inp_esc, out_uesc):
    par_esc = ContentLine.parse(inp_esc)
    par_uesc = attr.evolve(par_esc, value=TextConv.parse(par_esc.value))
    out_esc = attr.evolve(out_uesc, value=TextConv.serialize(out_uesc.value))
    assert par_uesc == out_uesc