Esempio n. 1
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")
Esempio n. 2
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]
Esempio n. 3
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", [])]
Esempio n. 4
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")
Esempio n. 5
0
 def parse_multiple(cls, string):
     """"
     Parses an input string that may contain mutiple calendars
     and retruns a list of :class:`ics.event.Calendar`
     """
     containers = string_to_container(string)
     return [cls(imports=c) for c in containers]
Esempio n. 6
0
    def __init__(self,
                 imports: Union[str, Container, None] = None,
                 events: Optional[Iterable[Event]] = None,
                 todos: Optional[Iterable[Todo]] = None,
                 creator: str = None,
                 **kwargs):
        """Initializes a new Calendar.

        Args:
            imports (**str**): data to be imported into the Calendar,
            events (**Iterable[Event]**): `Event`s to be added to the calendar
            todos (**Iterable[Todo]**): `Todo`s to be added to the calendar
            creator (**string**): uid of the creator program.
        """
        if events is None:
            events = tuple()
        if todos is None:
            todos = tuple()
        kwargs.setdefault("version", self.DEFAULT_VERSION)
        kwargs.setdefault(
            "prodid", creator if creator is not None else self.DEFAULT_PRODID)
        super(Calendar, self).__init__(events=events, todos=todos,
                                       **kwargs)  # type: ignore
        self.timeline = Timeline(self, None)

        if imports is not None:
            if isinstance(imports, Container):
                self.populate(imports)
            else:
                containers = string_to_container(imports)
                if len(containers) != 1:
                    raise ValueError(
                        "Multiple calendars in one file are not supported by this method."
                        "Use ics.Calendar.parse_multiple()")
                self.populate(containers[0])
Esempio n. 7
0
def test_any_name_params_value_recode(name, value, param1, p1value, param2, p2value1, p2value2):
    assume(param1 != param2)
    raw = "%s;%s=%s;%s=%s,%s:%s" % (name, param1, quote_escape_param(p1value),
                                    param2, quote_escape_param(p2value1), quote_escape_param(p2value2), value)
    assert ContentLine.parse(raw).serialize() == raw
    cl = ContentLine(name, {param1: [p1value], param2: [p2value1, p2value2]}, value)
    assert ContentLine.parse(cl.serialize()) == cl
    assert string_to_container(raw) == [cl]
Esempio n. 8
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]
Esempio n. 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]
Esempio n. 10
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]
Esempio n. 11
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)
Esempio n. 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)
Esempio n. 13
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]
Esempio n. 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]
Esempio n. 15
0
def read_tz(path):
    with open(path, "rt") as f:
        ics_cal = string_to_container(f.read())
        if not (len(ics_cal) == 1 and len(ics_cal[0]) == 3 and ics_cal[0][2].name == "VTIMEZONE"):
            raise ValueError("vTimezone.ics file %s has invalid content" % path)
        return Timezone.from_container(ics_cal[0][2])