From e9a968157e65e18d1b285a7765ecb641175ba370 Mon Sep 17 00:00:00 2001 From: Tobias Brox Date: Fri, 30 Sep 2022 01:29:58 +0200 Subject: More work on the kal aka cal.py command. It can now do around 80% of all the stuff calendar-cli can do, plus more. --- tests/test_cal.py | 131 +++++++++++++++++++++++++++ tests/test_calendar-cli.sh | 8 +- tests/tests.sh | 10 +-- tests/tests_kal.sh | 218 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 357 insertions(+), 10 deletions(-) create mode 100644 tests/test_cal.py create mode 100755 tests/tests_kal.sh (limited to 'tests') diff --git a/tests/test_cal.py b/tests/test_cal.py new file mode 100644 index 0000000..bfbd325 --- /dev/null +++ b/tests/test_cal.py @@ -0,0 +1,131 @@ +import pytest +import sys +sys.path.insert(0,'.') +sys.path.insert(1,'..') +from datetime import datetime, date +from cal import parse_timespec +from lib.template import Template + +"""calendar-cli is a command line utility, and it's an explicit design +goal that it should contain minimal logic except for parsing and +passing command line options and parameters to the caldav library and +printing output from the caldav library. Functional tests verifying +that the tool actually works as intended is done through shell +scripts, and can be run through test_calendar-cli.sh. There is no +goal to get complete code coverage through this unit test, though any +"extra" logic except for simple passing of options and parameters to +the caldav library ought to be tested here. """ + +class TestTemplate: + def setup(self): + self.date = date(1990, 10, 10) + + def test_formatting_with_timespec(self): + template=Template("This is an ISO date: {date:%F}") + text = template.format(date=self.date) + assert text == "This is an ISO date: 1990-10-10" + + text = template.format(foo=self.date) + assert text == "This is an ISO date: " + + def test_formatting_with_simple_default(self): + template=Template("This is an ISO date: {date:?(date is missing)?%F}") + text = template.format(date=self.date) + assert text == "This is an ISO date: 1990-10-10" + + text = template.format(foo=self.date) + assert text == "This is an ISO date: (date is missing)" + + def test_subvalue_with_default(self): + template = Template("This is a year: {date.year:?NA?>5}") + text = template.format(date=self.date) + assert text == "This is a year: 1990" + text = template.format(foo=self.date) + assert text == "This is a year: NA" + + def test_missing_replaced_with_advanced_default(self): + template = Template("Date is maybe {date:?{foo}?%F}") + text = template.format(date=self.date) + assert text == "Date is maybe 1990-10-10" + text = template.format(foo=self.date) + assert text == "Date is maybe 1990-10-10" + text = template.format(foo=self.date, date=self.date) + assert text == "Date is maybe 1990-10-10" + + def test_missing_replaced_with_even_more_advanced_default(self): + template = Template("Date is maybe {date:?{foo:?bar?}?%F}") + text = template.format(date=self.date) + assert text == "Date is maybe 1990-10-10" + text = template.format(foo=self.date) + assert text == "Date is maybe 1990-10-10" + text = template.format(foo=self.date, date=self.date) + assert text == "Date is maybe 1990-10-10" + text = template.format() + assert text == "Date is maybe bar" + +class TestParseTimestamp: + def _testTimeSpec(self, expected): + for input in expected: + assert parse_timespec(input) == expected[input] + + @pytest.mark.skip(reason="Not implemented yet, waiting for feedback on https://github.com/gweis/isodate/issues/77") + def testIsoIntervals(self): + raise pytest.SkipTest("") + expected = { + "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z": + (datetime(2007,3,1,13), datetime(2008,5,11,15,30)), + "2007-03-01T13:00:00Z/P1Y2M10DT2H30M": + (datetime(2007,3,1,13), datetime(2008,5,11,15,30)), + "P1Y2M10DT2H30M/2008-05-11T15:30:00Z": + (datetime(2007,3,1,13), datetime(2008,5,11,15,30)) + } + self._testTimeSpec(expected) + + def testOneTimestamp(self): + expected = { + "2007-03-01T13:00:00": + (datetime(2007,3,1,13), None), + "2007-03-01 13:00:00": + (datetime(2007,3,1,13), None), + } + self._testTimeSpec(expected) + + def testOneDate(self): + expected = { + "2007-03-01": + (date(2007,3,1), None) + } + self._testTimeSpec(expected) + + def testTwoTimestamps(self): + expected = { + "2007-03-01T13:00:00 2007-03-11T13:30:00": + (datetime(2007,3,1,13), datetime(2007,3,11,13,30)), + "2007-03-01 13:00:00 2007-03-11 13:30:00": + (datetime(2007,3,1,13), datetime(2007,3,11,13,30)), + } + self._testTimeSpec(expected) + + def testTwoDates(self): + expected = { + "2007-03-01 2007-03-11": + (date(2007,3,1), date(2007,3,11)) + } + self._testTimeSpec(expected) + + def testCalendarCliFormat(self): + expected = { + "2007-03-01T13:00:00+10d": + (datetime(2007,3,1,13), datetime(2007,3,11,13)), + "2007-03-01T13:00:00+2h": + (datetime(2007,3,1,13), datetime(2007,3,1,15)), + "2007-03-01T13:00:00+2.5h": + (datetime(2007,3,1,13), datetime(2007,3,1,15,30)), + "2007-03-01T13:00:00+2h30m": + (datetime(2007,3,1,13), datetime(2007,3,1,15,30)), + "2007-03-01+10d": + (date(2007,3,1), date(2007,3,11)) + } + self._testTimeSpec(expected) + + diff --git a/tests/test_calendar-cli.sh b/tests/test_calendar-cli.sh index b45d596..8e408e2 100755 --- a/tests/test_calendar-cli.sh +++ b/tests/test_calendar-cli.sh @@ -3,7 +3,7 @@ storage=$(mktemp -d) echo "This script will attempt to set up a Radicale server and a Xandikos server and run the test code towards those two servers" -echo "The test code itself is found in tests.sh" +echo "The test code itself is found in tests.sh and tests_kal.sh" export RUNTESTSNOPAUSE="foo" @@ -31,7 +31,8 @@ then echo "press enter to run tests" read foo fi - ./tests.sh + ./tests_kal.sh + #./tests.sh if [ -n "$DEBUG" ] then echo "press enter to take down test server" @@ -62,7 +63,8 @@ then kal="../cal.py --caldav-url=http://localhost:8080/ --caldav-user=user" export calendar_cli export kal - ./tests.sh + ./tests_kal.sh + #./tests.sh kill $xandikos_pid else echo "## Could not start up xandikos (is it installed?). Will skip running tests towards xandikos" diff --git a/tests/tests.sh b/tests/tests.sh index bd1fbfb..1c91270 100755 --- a/tests/tests.sh +++ b/tests/tests.sh @@ -22,7 +22,6 @@ then echo "This script will use the following commands to access a calendar server:" echo echo "$calendar_cli" - echo "$kal" echo echo "This may work if you have configured a calendar server." echo "The tests will add and delete events and tasks." @@ -77,7 +76,7 @@ echo "## Deleting events with uid $uid $uid1 $uid2" calendar_cli calendar delete --event-uid=$uid calendar_cli calendar delete --event-uid=$uid2 calendar_cli calendar delete --event-uid=$uid3 -kal select --uid=$uid3 delete + echo "## Searching again for the deleted event" calendar_cli calendar agenda --from-time=2010-10-10 --agenda-days=3 echo $output | { grep -q 'testing testing' && error "still found the event" ; } || echo "## OK: didn't find the event" @@ -103,7 +102,7 @@ echo "## cleanup, delete it" calendar_cli calendar delete --event-uid=$uid echo "## Same, using kal add ics" -kal add ical --ical-file=$tmpfile +calendar_cli calendar addics --file $tmpfile rm $tmpfile calendar_cli --icalendar calendar agenda --from-time=2010-10-13 --agenda-days=1 @@ -115,8 +114,6 @@ echo "## cleanup, delete it" calendar_cli calendar delete --event-uid=$uid ## TODO - procrastinated, waiting for response on https://github.com/dateutil/dateutil/issues/1184 -#echo "## Same, using kal add event" -#kal add event '2010-10-10+4d' 'whole day testing' #uid=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') #[ -n "$uid" ] || error "got no UID back" #calendar_cli --icalendar calendar agenda --from-time=2010-10-13 --agenda-days=1 @@ -184,7 +181,7 @@ echo "## TODOS / TASK LISTS" echo "## Attempting to add a task with category 'scripttest'" calendar_cli todo add --set-categories scripttest "edit this task" uidtodo1=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') -kal add --set-categories scripttest todo "edit this task2" +calendar_cli todo add --set-categories scripttest todo "edit this task2" uidtodo2=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') echo "## Listing out all tasks with category set to 'scripttest'" @@ -193,7 +190,6 @@ calendar_cli todo --categories scripttest list echo "## Editing the task" calendar_cli todo --categories scripttest edit --set-summary "editing" --add-categories "scripttest2" -#kal select --todo --categories scripttest edit --add-categories "scripttest3" echo "## Verifying that the edits got through" calendar_cli todo --categories scripttest list diff --git a/tests/tests_kal.sh b/tests/tests_kal.sh new file mode 100755 index 0000000..3858063 --- /dev/null +++ b/tests/tests_kal.sh @@ -0,0 +1,218 @@ +#!/bin/bash + +## TODO: all references to calendar-cli should be replaced with references to kal. Work in progress! + +set -e + +######################################################################## +## SETUP +######################################################################## + +for path in . .. ./tests ../tests +do + setup="$path/_setup_alias" + [ -f $setup ] && source $setup +done + +if [ -z "$RUNTESTSNOPAUSE" ] +then + echo "tests.sh" + echo + echo "Generally, tests.sh should only be run directly if you know what you are doing" + echo "You may want to use test_calendar-cli.sh instead" + echo + echo "This script will use the following commands to access a calendar server:" + echo + echo "$kal" + echo "$calendar_cli" + echo + echo "This may work if you have configured a calendar server." + echo "The tests will add and delete events and tasks." + echo "Content from 2010-10 may be deleted" + echo + echo "Press enter or ctrl-C" + read foo +fi + +echo "## CLEANUP from earlier failed test runs, if any" + +QUIET=true +for uid in $($calendar_cli calendar agenda --from-time=2010-10-09 --agenda-days=5 --event-template='{uid}') ; do calendar_cli calendar delete --event-uid=$uid ; done +calendar_cli todo --categories scripttest delete +unset QUIET + +######################################################################## +## TEST CODE FOLLOWS +######################################################################## + +echo "## EVENTS" + +echo "## this is a very simple test script without advanced error handling" +echo "## if this test script doesn't output 'ALL TESTS COMPLETED! YAY!' in the end, something went wrong" + +echo "## Attempting to add an event at 2010-10-09 20:00:00, 2 hours duration" +kal add event 'testing testing' '2010-10-09 20:00:00+2h' +uid=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +[ -n "$uid" ] || error "got no UID back" + +echo "## Attempting to add an event at 2010-10-10 20:00:00, CET (1 hour duration is default), with description and non-ascii location" +kal add event 'testing testing' '2010-10-10 20:00:00+01:00' --set-description='this is a test calendar event' --set-location='Москва' +uid2=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +[ -n "$uid2" ] || error "got no UID back" + +echo "## Attempting to add an event at 2010-10-11 20:00:00, CET, 3h duration" +kal add event 'testing testing' '2010-10-11 20:00:00+01:00+3h' +uid3=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +echo "## OK: Added the event, uid is $uid" + +echo "## Taking out the agenda for 2010-10-09 + four days" +kal select --start=2010-10-09 --end=+4d --event list --template='{DESCRIPTION} {LOCATION}' +echo $output | { grep -q 'this is a test calendar event Москва' && echo "## OK: found the event" ; } || error "didn't find the event" + +echo "## Taking out the agenda for 2010-10-10, with uid" +kal select --start=2010-10-10 --end=+1d --event list --template='{DTSTART.dt} {UID}' +echo $output | { grep -q $uid2 && echo "## OK: found the UID" ; } || error "didn't find the UID" + +echo "## Deleting events with uid $uid $uid2 $uid3" +kal select --event --uid=$uid delete +kal select --event --uid=$uid2 delete +kal select --event --uid=$uid3 delete + +echo "## Searching again for the deleted event" +kal select --event --start=2010-10-10 --end=+3d list +echo $output | { grep -q 'testing testing' && error "still found the event" ; } || echo "## OK: didn't find the event" + +echo "## Adding a full day event" +kal add event 'whole day testing' '2010-10-10+4d' +uid=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +[ -n "$uid" ] || error "got no UID back" + +echo "## fetching the full day event, in ics format" +kal select --start=2010-10-13 --end=+1d --event list --ics + +echo "$output" | grep -q "whole day" || error "could not find the event" +echo "$output" | grep -q "20101010" || error "could not find the date" +echo "$output" | grep -q "20101010T" && error "a supposed whole day event was found to be with the time of day" +echo "OK: found the event" + +## saving the ics data +tmpfile=$(mktemp) +cat $outfile > $tmpfile + +echo "## cleanup, delete it" +kal select --event --uid=$uid delete + +echo "## Same, using kal add ics" +kal add ical --ical-file=$tmpfile +rm $tmpfile + +kal select --event --start=2010-10-13 --end=2010-10-14 list --ics +echo "$output" | grep -q "whole day" || error "could not find the event" +echo "$output" | grep -q "20101010" || error "could not find the date" +echo "$output" | grep -q "20101010T" && error "a supposed whole day event was found to be with the time of day" +echo "$output" | grep UID +echo "OK: found the event" +echo "## cleanup, delete it" + +kal select --event --uid=$uid delete + +## TODO: PROCRASTINATING TIME ZONES. Waiting for a release of the icalendar library that doesn't depend on pytz +if [ -n "" ]; then +echo "## testing timezone support" +echo "## Create a UTC event" +calendar_cli --timezone='UTC' calendar add '2010-10-09 12:00:00+10m' 'testevent with a UTC timezone' +uid=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +[ -n "$uid" ] || error "got no UID back" + +echo "## fetching the UTC-event, as ical data" +calendar_cli --icalendar --timezone=UTC calendar agenda --from-time='2010-10-09 11:59' --agenda-mins=3 +[ -n "$output" ] || error "failed to find the event that was just added" +echo "$output" | grep -q "20101009T120000Z" || error "failed to find the UTC timestamp. Perhaps the server is yielding timezone data for the UTC timezone? In that case, the assert in the test code should be adjusted" + +echo "## cleanup, delete it" +calendar_cli calendar delete --event-uid=$uid + +echo "## Create an event with a somewhat remote time zone, west of UTC" +calendar_cli --timezone='Brazil/DeNoronha' calendar add '2010-10-09 12:00:00+10m' 'testevent with a time zone west of UTC' +uid=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +[ -n "$uid" ] || error "got no UID back" + +echo "## fetching the remote time zone event, as ical data" +calendar_cli --icalendar --timezone=UTC calendar agenda --from-time='2010-10-09 13:59' --agenda-mins=3 +## zimbra changes Brazil/DeNoronha to America/Noronha. Actually, the server may theoretically use arbitrary IDs for the timezones. +echo "$output" | grep -Eq "TZID=\"?[a-zA-Z/]*Noronha" || echo "$output" | grep -q "140000Z" || + error "failed to find the remote timezone" + +echo "## fetching the remote time zone event, in UTC-time" +calendar_cli --timezone=UTC calendar agenda --from-time='2010-10-09 13:59' --agenda-mins=3 --event-template='{dtstart}' +[ "$output" == '2010-10-09 14:00 (Sat)' ] || error "expected dtstart to be 2010-10-09 14:00 (Sat)" + +echo "## fetching the remote time zone event, in CET-time (UTC+2 with DST, and October is defined as summer in Oslo, weird)" +calendar_cli --timezone=Europe/Oslo calendar agenda --from-time='2010-10-09 15:59' --agenda-mins=3 --event-template='{dtstart}' +[ "$output" == '2010-10-09 16:00 (Sat)' ] || error "expected dtstart to be 2010-10-09 15:00 (Sat)" + +echo "## cleanup, delete it" +calendar_cli calendar delete --event-uid=$uid +fi + +echo "## TODOS / TASK LISTS" + +echo "## Attempting to add a task with category 'scripttest'" +kal add todo --set-category scripttest "edit this task" +uidtodo1=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +kal add todo --set-category scripttest "edit this task2" +uidtodo2=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') + +echo "## Listing out all tasks with category set to 'scripttest'" +kal select --todo --category scripttest list +[ $(echo "$output" | wc -l) == 2 ] || error "We found more or less or none of the two todo items we just added" + +echo "## Editing the task" +kal select --todo --category scripttest edit --set-summary "editing" --add-category "scripttest2" + +echo "## Verifying that the edits got through" +kal select --todo --category scripttest list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found the todo item we just edited and nothing more" +kal select --todo --category scripttest2 list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found the todo item we just edited and nothing more" +kal select --todo --category scripttest3 list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found the todo item we just edited and nothing more" +kal select --todo --comment editing list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found the todo item we just edited and nothing more" + +if [ -n "" ]; then +echo "## Complete the task" +calendar_cli todo --categories scripttest complete +calendar_cli todo --categories scripttest list +[ -z "$output" ] && echo "## OK: todo-item is done" +calendar_cli todo --todo-uid $uidtodo1 delete + +## parent-child relationships +echo "## Going to add three todo-items with children/parent relationships" +calendar_cli todo add --set-categories scripttest "this is a grandparent" +uidtodo2=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +calendar_cli todo --categories=scripttest add --set-categories scripttest --is-child "this is a parent and a child" +uidtodo3=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +calendar_cli todo --categories=scripttest add --set-categories scripttest --is-child "this task has two parents" +uidtodo4=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +calendar_cli todo --categories scripttest list +[ $(echo "$output" | wc -l) == 3 ] && echo "## OK: found three tasks" +calendar_cli todo --hide-parents --categories scripttest list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found only one task now" +echo "## Going to complete the children task" +calendar_cli todo --hide-parents --categories scripttest complete +calendar_cli todo --hide-parents --categories scripttest list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found only one task now" +calendar_cli todo --hide-parents --categories scripttest complete +calendar_cli todo --hide-parents --categories scripttest list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found only one task now" +calendar_cli todo --hide-parents --categories scripttest complete +calendar_cli todo --hide-parents --categories scripttest list +[ -z "$output" ] && echo "## OK: found no tasks now" + +fi + +echo "## some kal TESTS COMPLETED SUCCESSFULLY! YAY!" + +rm $outfile + -- cgit v1.2.3