]> infiniteadaptability.org Git - events/commitdiff
Bugfixes v1.0.1
authoralex <[email protected]>
Mon, 2 Jan 2023 08:08:16 +0000 (00:08 -0800)
committeralex <[email protected]>
Mon, 2 Jan 2023 19:23:02 +0000 (11:23 -0800)
Fixed recur across year/month boundaries not working properly
Improved timezone handling
Fixed prune not re-adding recurring events
Refactored recur functionality into own function

33 files changed:
Makefile.am
completions/ev
configure.ac
inc/args.h
inc/event.h
inc/main.h
inc/prune.h
inc/recur.h [new file with mode: 0644]
inc/rm.h
inc/validate.h [new file with mode: 0644]
man/ev.1
src/args.c
src/event/parse.c
src/event/serial.c
src/event/time.c
src/ls.c
src/main.c
src/prune.c
src/recur.c [new file with mode: 0644]
src/rm.c
src/validate.c [new file with mode: 0644]
test/unit/Makefile.am
test/unit/add.tests.c
test/unit/args.tests.c
test/unit/event.tests.c
test/unit/ls.tests.c
test/unit/opt.tests.c
test/unit/postpone.tests.c
test/unit/prune.tests.c
test/unit/recur.tests.c [new file with mode: 0644]
test/unit/rm.tests.c
test/unit/test_utils.c
test/unit/validate.tests.c [new file with mode: 0644]

index 4ad2767fc495c95199491bd273363f38496a14f6..7fafde0a67efe22c933b988868af62feebb87b73 100644 (file)
@@ -39,9 +39,11 @@ ev_SOURCES = \
        src/opt/until.c \
        src/postpone.c \
        src/prune.c \
+       src/recur.c \
        src/rm.c \
        src/seek.c \
-       src/usage.c
+       src/usage.c \
+       src/validate.c
 
 ev_SOURCES += \
        inc/add.h \
@@ -56,9 +58,11 @@ ev_SOURCES += \
        inc/opt.h \
        inc/postpone.h \
        inc/prune.h \
+       inc/recur.h \
        inc/rm.h \
        inc/seek.h \
-       inc/usage.h
+       inc/usage.h \
+       inc/validate.h
 
 man_MANS = man/ev.1
 
index 96991f87d8b26875876398ab38375d77a702b308..aa2f9d8e56b4da98ae70af01d43af6862f88102f 100644 (file)
@@ -1,7 +1,7 @@
 _ev() {
        IFS=$'\n'
        COMPREPLY=()
-       local commands=$'add\ndismiss\nls\npostpone\nprune\nrm'
+       local commands=$'add\ndismiss\nls\npostpone\nprune\nrm\nvalidate'
 
        declare -A options
        options[--all]="--all"
@@ -76,6 +76,7 @@ _ev() {
                        echo "$rmformat"
                        COMPREPLY=()
                        ;;
+               validate) ;;
                ev)
                        COMPREPLY=($(compgen -W "${commands}" -- "$2"))
                        COMPREPLY+=($(compgen -W "${opts}" -- "$2"))
@@ -88,6 +89,6 @@ _ev() {
                        COMPREPLY=()
                        ;;
        esac
-} >> /tmp/ev.output
+}
 
 complete -F _ev ev
index 1461b9dff6d6be716c32be29a217f64be0df36bc..ed5a483a6efad166e14a4c920d97cbd9a1b0f999 100644 (file)
@@ -50,7 +50,7 @@ AC_PROG_INSTALL
 # Checks for libraries.
 
 # Checks for header files.
-AC_CHECK_HEADERS([limits.h stdlib.h string.h unistd.h])
+AC_CHECK_HEADERS([limits.h stdlib.h string.h time.h unistd.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_TYPE_SIZE_T
index e51829894b5ae3ccd47c8fcc7a633d10cf3ea37d..ebda10bd79b05de84df3134be77725825e444696 100644 (file)
@@ -13,7 +13,8 @@ enum sub_command {
        SUB_COMMAND_LS,
        SUB_COMMAND_POSTPONE,
        SUB_COMMAND_PRUNE,
-       SUB_COMMAND_RM
+       SUB_COMMAND_RM,
+       SUB_COMMAND_VALIDATE
 };
 
 int args(int,char**);
index 87670d9e77a104a64ae8b3903c1ca26380852bcb..390253fda3ae61de76b1267dbf0854553b88196f 100644 (file)
@@ -58,6 +58,7 @@ int event_parse(char*, size_t, struct event*);
 int event_place_set(struct event*, const char*);
 int event_serialize(char*, size_t, const struct event*);
 int event_time_compare(const struct tm*,time_t);
+int event_time_date_only(const struct tm*);
 int event_time_set(struct tm*, const char*);
 int event_within(struct event*, struct event_filter*);
 
index 7cca03ea4074ca857472b7ee4605dc8a4092ca6f..35304aea191ac9f083d626ed4ac95b040f78c91b 100644 (file)
@@ -11,6 +11,7 @@
 #include<postpone.h>
 #include<prune.h>
 #include<rm.h>
+#include<validate.h>
 
 int main(int,char**);
 
index f45aaccb64c58e07133df6ff0972452a5148a09c..73ad3792535e3f71a0528f134646f18ec0ddd665 100644 (file)
@@ -5,6 +5,7 @@
 #include<stdlib.h>
 
 #include<file.h>
+#include<recur.h>
 #include<seek.h>
 
 int prune();
diff --git a/inc/recur.h b/inc/recur.h
new file mode 100644 (file)
index 0000000..9c7710a
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __RECUR_H_
+#define __RECUR_H_
+
+#include<event.h>
+
+int recur(struct event*);
+
+#endif
index d93856eee1a511e901ddf11be7405c7ce8789d25..bf5e4e58145713701c23453c60ab07e4f8226fbe 100644 (file)
--- a/inc/rm.h
+++ b/inc/rm.h
@@ -9,6 +9,7 @@
 #include<cut.h>
 #include<event.h>
 #include<file.h>
+#include<recur.h>
 
 #define RM_FLAG_DISMISS 1
 
diff --git a/inc/validate.h b/inc/validate.h
new file mode 100644 (file)
index 0000000..ae54922
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __VALIDATE_H_
+#define __VALIDATE_H_
+
+#include<stdio.h>
+#include<string.h>
+
+#include<file.h>
+
+int validate();
+
+#endif
index 53c19535a8a2bc6563af16dbb7bf0a52ed55b44a..1ceb378f11858c89d81028d165445f730d517a9c 100644 (file)
--- a/man/ev.1
+++ b/man/ev.1
@@ -1,4 +1,4 @@
-.TH EV "1" "2022 September 13" "v0.0.0" "Events"
+.TH EV "1" "2022 September 13" "v1.0.0" "Events"
 
 .SH NAME
 ev \- human readable events organizer
@@ -37,6 +37,8 @@ If no COMMAND is specified, COMMAND defaults to ls.
 .B prune
 .IP \(bu
 .B rm
+.IP \(bu
+.B validate
 
 .SH OPTIONS
 .TP
@@ -167,6 +169,11 @@ postpones event in the 0th position by 1 day
 .B
 ev postpone 0
 
+.TP
+validate events file format
+.B
+ev validate
+
 .SH "SEE ALSO"
 .BR git (1)
 
index 2fc32e3a757e7d0e653dae9e1b5459cb019c9e80..0efdb5fe527621b2c75963c6de29727c10db4466 100644 (file)
@@ -70,6 +70,7 @@ enum sub_command args(int argc, char **argv) {
        if(strcmp(argv[optind],"postpone")==0) { return SUB_COMMAND_POSTPONE; }
        if(strcmp(argv[optind],"prune")==0) { return SUB_COMMAND_PRUNE; }
        if(strcmp(argv[optind],"rm")==0) { return SUB_COMMAND_RM; }
+       if(strcmp(argv[optind],"validate")==0) { return SUB_COMMAND_VALIDATE; }
 
        goto fail;
 fail:
index b1cf3d1ab4217d5839314370296702fa45a3e395..58d6a07e09e8f2ca0b5dcc664ff1af134ce56abf 100644 (file)
@@ -28,6 +28,8 @@ static int event_parse_name(char *buf, size_t buf_size, struct event *ev) {
                token = normal;
        }
 
+       if(strlen(buf)<1) { return -1; }
+
        p = strtok(buf,token);
        if(p!=NULL) {
                if(event_name_set(ev,p)<0) { return -1; }
@@ -127,7 +129,11 @@ static int event_parse_time(char *buf, size_t buf_size, struct event *ev) {
 
        if(event_time_set(&(ev->datetime),buf)<0) { return -1; }
 
-       memmove(buf,p,(buf_size - (p - buf)));
+       if((buf_size - (p - buf))>0) {
+               memmove(buf,p,(buf_size - (p - buf)));
+       } else {
+               buf[0] = '\0';
+       }
 
        return 1;
 }
index df202255891c7d8ad94d3733dcabc1e4ccdbd40a..64381c748285b48ff17dbc395776cc8f629b8ae0 100644 (file)
@@ -97,13 +97,13 @@ static int event_serialize_place(char *buf, size_t buf_size, const struct event
 }
 
 static int event_serialize_time(char *buf, size_t buf_size, const struct tm *datetime) {
-       size_t len;
+       size_t len, i;
 
        assert(buf!=NULL);
 
        len = strlen(buf);
        
-       if(datetime->tm_sec==0 && datetime->tm_min==0 && datetime->tm_hour == 0) {
+       if(event_time_date_only(datetime)>0) {
                if(0==strftime(
                        &(buf[len]), /* char *s */
                        buf_size - len, /* size_t max */
@@ -111,12 +111,18 @@ static int event_serialize_time(char *buf, size_t buf_size, const struct tm *dat
                        datetime /* const struct tm *tm */
                        )) { return -1; }
        } else {
-               if(0==strftime(
+               long offset = datetime->__tm_gmtoff;
+
+               i = strftime(
                        &(buf[len]), /* char *s */
                        buf_size - len, /* size_t max */
-                       "%Y-%m-%d %H:%M:%S %z", /* const char *format */
+                       "%Y-%m-%d %H:%M:%S ", /* const char *format */
                        datetime /* const struct tm *tm */
-                       )) { return -1; }
+                       );
+               if(i==0) { return -1; }
+
+               len += i;
+               if(snprintf(&(buf[len]),buf_size - len,"%+.2li%.2li", offset/3600, offset%60)<0) { return -1; }
        }
 
        return 1;
index 1a46aaf274687487712205831ff7e9116cfb6821..0245b440d2776c2d965c9a214914bb95ec3cab5c 100644 (file)
@@ -14,25 +14,38 @@ int event_time_compare(const struct tm *datetime, time_t time) {
        return 0;
 }
 
+int event_time_date_only(const struct tm *date) {
+       if((*date).tm_sec != 0) { return -1; }
+       if((*date).tm_min != 0) { return -1; }
+       if((*date).tm_hour != 0) { return -1; }
+       return 1;
+}
+
 int event_time_set(struct tm *datetime, const char *str) {
        const char *p;
-
-       p = str;
+       
+       /* this call is necessary here to guarantee
+        * that extern int daylight is set correctly.
+        * see man tzset.
+        */
+       //tzset();
 
        memset(datetime, 0, sizeof(struct tm));
+       datetime->tm_isdst = -1;
 
        /* minimum expected date format */
-       p = strptime(p,"%Y-%m-%d",datetime);
-       if(NULL==p) { return -1; }
-       
-       /* attempt to get time information */
-       p = strptime(p,"%H:%M:%S",datetime);
+       p = strptime(str,"%Y-%m-%d %H:%M:%S %z",datetime);
+       if(p!=NULL) { return 1; }
 
-       /* attempt to get timezone information */
+       p = strptime(str,"%Y-%m-%d %H:%M:%S",datetime);
        if(p!=NULL) {
-               strptime(p,"%z",datetime);
+               if(mktime(datetime)<0) { return -1; }
+               return 1;
        }
 
+       p = strptime(str,"%Y-%m-%d",datetime);
+       if(NULL==p) { return -1; }
+       
        return 1;
 }
 
index 52564f6c2bc9cd51cea1fa311a9efc31438d5efd..480dc7360f6b2a3b6ee9712032da977f57e2f351 100644 (file)
--- a/src/ls.c
+++ b/src/ls.c
@@ -35,19 +35,26 @@ close:
 }
 
 static int event_print(struct event *ev) {
+       char datebuf[20];
+       time_t timestamp;
+       struct tm *local;
+       long offset;
+
        assert(ev!=NULL);
 
        if(NULL==ev->name) { return -1; }
 
-       char datebuf[20];
-       if(
-               (ev->datetime.tm_sec==0) &&
-               (ev->datetime.tm_min == 0) &&
-               (ev->datetime.tm_hour == 0)
-         ) {
+       if(event_time_date_only(&(ev->datetime))>0) {
                if(strftime(datebuf,20,"%Y-%m-%d",&(ev->datetime))!=10) { return -1; }
        } else {
-               if(strftime(datebuf,20,"%Y-%m-%d %H:%M:%S",&(ev->datetime))!=19) { return -1; }
+               offset = ev->datetime.tm_gmtoff;
+               timestamp = timegm(&(ev->datetime)) - offset;
+               if(timestamp<0) { return -1; }
+
+               local = localtime(&timestamp);
+               if(NULL==local) { return -1; }
+
+               if(strftime(datebuf,20,"%Y-%m-%d %H:%M:%S",local)!=19) { return -1; }
        }
 
        if(fprintf(stdout,"%-20s\t",datebuf)<0) { return -1; }
index 52bf386eb1d6e72183c2b208de153776e21870b1..bd3f4e5280c95d26d503f04f3a8a2c53cd87a4dd 100644 (file)
@@ -22,6 +22,8 @@ int main(int argc, char **argv) {
                        return prune();
                case SUB_COMMAND_RM:
                        return rm(argc,argv,0);
+               case SUB_COMMAND_VALIDATE:
+                       return validate();
                default:
                        return EXIT_FAILURE;
        }
index 0c3bc44a79beb7d0ba9a3f810b3c18d899f902ff..422f5f8c585c9f2138a17c5fcc48f8cb79704000 100644 (file)
@@ -1,5 +1,43 @@
 #include<prune.h>
 
+static int copy_recur_events(FILE*,FILE*);
+
+static int copy_recur_events(FILE *src, FILE *to) {
+       char buf[EVENT_SERIALIZE_MAX_LENGTH];
+       struct event ev;
+       time_t now;
+       ssize_t i;
+
+       now = time(NULL);
+
+       memset(buf,0,EVENT_SERIALIZE_MAX_LENGTH);
+       while((i = file_line_next(buf,EVENT_SERIALIZE_MAX_LENGTH,src))>0) {
+               if(event_parse(buf,EVENT_SERIALIZE_MAX_LENGTH,&ev)<0) { return -1; }
+
+               if(event_time_compare(&(ev.datetime),now)>0) {
+                       event_free(&ev);
+                       if(fseek(src,-i,SEEK_CUR)!=0) { return -1; }
+                       break;
+               }
+
+               switch(recur(&ev)) {
+                       case -1:
+                               event_free(&ev);
+                               return -1;
+                       case 1:
+                               if(event_serialize(buf,EVENT_SERIALIZE_MAX_LENGTH,&ev)<0) { return -1; }
+                               if(fwrite(buf,1,i,to)!=i) { return -1; }
+                               break;
+                       default:
+                               event_free(&ev);
+                               memset(buf,0,EVENT_SERIALIZE_MAX_LENGTH);
+                               break;
+               }
+       }
+
+       return 1;
+}
+
 int prune() {
        FILE *src, *to;
 
@@ -10,8 +48,8 @@ int prune() {
        src = file_open();
        if(NULL==src) { return EXIT_FAILURE; }
 
-       if(seek(src,time(NULL))<0) { return EXIT_FAILURE; }
-
+       if(copy_recur_events(src,to)<0) { return EXIT_FAILURE; }
+       
        if(file_pipe(to,src)<0) { return EXIT_FAILURE; }
 
        if(fclose(src)!=0) { return EXIT_FAILURE; }
diff --git a/src/recur.c b/src/recur.c
new file mode 100644 (file)
index 0000000..8aec402
--- /dev/null
@@ -0,0 +1,54 @@
+#include<recur.h>
+
+int recur(struct event *ev) {
+       time_t compare;
+       struct tm tm;
+
+       if(ev->options.recur==0) { return 0; }
+       
+       memcpy(&tm,&(ev->datetime),sizeof(struct tm));
+
+       switch(ev->options.recur_period) {
+               case TIME_PERIOD_YEAR:
+                       tm.tm_year += ev->options.recur;
+                       break;
+               case TIME_PERIOD_MONTH:
+                       tm.tm_mon += ev->options.recur;
+                       break;
+               case TIME_PERIOD_WEEK:
+                       tm.tm_mday += 7*(ev->options.recur);
+                       break;
+               case TIME_PERIOD_DAY:
+                       tm.tm_mday += ev->options.recur;
+                       break;
+               case TIME_PERIOD_HOUR:
+                       tm.tm_hour += ev->options.recur;
+                       break;
+               case TIME_PERIOD_MINUTE:
+                       tm.tm_min += ev->options.recur;
+                       break;
+               case TIME_PERIOD_SECOND:
+                       tm.tm_sec += ev->options.recur;
+                       break;
+               default:
+                       return -1;
+       }
+
+       tm.tm_isdst = -1;
+       compare = mktime(&tm);
+       if(compare<0) { return -1; }
+
+       ev->datetime.tm_year = tm.tm_year;
+       ev->datetime.tm_mon = tm.tm_mon;
+       ev->datetime.tm_mday = tm.tm_mday;
+       ev->datetime.tm_hour = tm.tm_hour;
+       ev->datetime.tm_min = tm.tm_min;
+       ev->datetime.tm_sec = tm.tm_sec;
+       ev->datetime.tm_wday = tm.tm_wday;
+
+       if(event_time_compare(&(ev->options.until),0)>0) {
+               if(event_time_compare(&(ev->options.until),compare)<0) { return 0; }
+       }
+
+       return 1;
+}
index 819996f6925b28c707bd4378639e389884dee65d..29adea4a30559ae3d7135b830aa165c2c52dbb8f 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
@@ -6,42 +6,16 @@ static int handle_args(int,char**,unsigned long int*, time_t *);
 static int check_need_readd(struct event *ev) {
        char buf[EVENT_SERIALIZE_MAX_LENGTH];
        char timebuf[40];
-       struct tm tm;
 
        assert(ev!=NULL);
 
-       if(ev->options.recur==0) { return 1; }
-
-
-       switch(ev->options.recur_period) {
-               case TIME_PERIOD_YEAR:
-                       ev->datetime.tm_year += ev->options.recur;
-                       break;
-               case TIME_PERIOD_MONTH:
-                       ev->datetime.tm_mon += ev->options.recur;
-                       break;
-               case TIME_PERIOD_WEEK:
-                       ev->datetime.tm_mday += 7*(ev->options.recur);
-                       break;
-               case TIME_PERIOD_DAY:
-                       ev->datetime.tm_mday += ev->options.recur;
-                       break;
-               case TIME_PERIOD_HOUR:
-                       ev->datetime.tm_hour += ev->options.recur;
-                       break;
-               case TIME_PERIOD_MINUTE:
-                       ev->datetime.tm_min += ev->options.recur;
-                       break;
-               case TIME_PERIOD_SECOND:
-                       ev->datetime.tm_sec += ev->options.recur;
-                       break;
-               default:
+       switch(recur(ev)) {
+               case -1:
                        return -1;
-       }
-
-       memcpy(&tm,&(ev->datetime),sizeof(struct tm));
-       if(event_time_compare(&(ev->options.until),0)>0) {
-               if(event_time_compare(&(ev->options.until),mktime(&tm))<0) { return 1; }
+               case 0:
+                       return 1;
+               default:
+                       break;
        }
 
        strftime(timebuf,40,"%a, %d %b %Y %T %z",&(ev->datetime));
diff --git a/src/validate.c b/src/validate.c
new file mode 100644 (file)
index 0000000..e0025e9
--- /dev/null
@@ -0,0 +1,37 @@
+#include<validate.h>
+
+int validate() {
+       char buf[EVENT_SERIALIZE_MAX_LENGTH];
+       struct event ev;
+       FILE *src;
+       ssize_t i;
+       size_t line;
+
+       src = file_open();
+       if(NULL==src) { return EXIT_FAILURE; }
+       
+       line = 1;
+       memset(buf,0,EVENT_SERIALIZE_MAX_LENGTH);
+       while((i = file_line_next(buf,EVENT_SERIALIZE_MAX_LENGTH,src))>0) {
+               if(event_parse(buf,EVENT_SERIALIZE_MAX_LENGTH,&ev)<0) {
+                       fprintf(stderr,"invalid event: event on line %lu failed to parse\n",line);
+                       return EXIT_FAILURE;
+               }
+
+               event_free(&ev);
+               memset(buf,0,EVENT_SERIALIZE_MAX_LENGTH);
+
+               line++;
+       }
+       
+       if(i<0) {
+               if(ferror(src)!=0) {
+                       fprintf(stderr,"failed to get line");
+                       return EXIT_FAILURE;
+               }
+       }
+
+       fprintf(stdout,"%s: \x1B[32mVALID\x1B[0m\n",global_options.file);
+
+       return EXIT_SUCCESS;
+}
index ba94b39e561cc955381b5592c9f9890f52fa4521..59267cd8d6249dfff6016460fc3b0b559f528cc0 100644 (file)
@@ -6,7 +6,7 @@ EXTRA_DIST = \
        test_macros.h \
        test_utils.h
 
-check_PROGRAMS = add.tests args.tests copy.tests cut.tests event.tests file.tests ls.tests opt.tests postpone.tests prune.tests rm.tests seek.tests usage.tests
+check_PROGRAMS = add.tests args.tests copy.tests cut.tests event.tests file.tests ls.tests opt.tests postpone.tests prune.tests recur.tests rm.tests seek.tests usage.tests validate.tests
 TESTS = $(check_PROGRAMS)
 
 if ENABLE_MEMCHECK
@@ -96,7 +96,8 @@ ls_tests_SOURCES = \
        $(event_SOURCES) \
        ls.tests.c \
        $(top_srcdir)/src/file/line.c \
-       $(top_srcdir)/src/file/open.c
+       $(top_srcdir)/src/file/open.c \
+       $(top_srcdir)/src/file/tmp.c
 
 ls_tests_CPPFLAGS = $(AM_CPPFLAGS) \
        -DLS_SRC_FILE="$(top_srcdir)/src/ls.c"
@@ -138,8 +139,15 @@ prune_tests_SOURCES = \
        $(top_srcdir)/src/file/pipe.c \
        $(top_srcdir)/src/file/tmp.c \
        $(top_srcdir)/src/prune.c \
+       $(top_srcdir)/src/recur.c \
        $(top_srcdir)/src/seek.c
 
+recur_tests_SOURCES = \
+       $(common_SOURCES) \
+       $(event_SOURCES) \
+       recur.tests.c \
+       $(top_srcdir)/src/recur.c
+
 rm_tests_SOURCES = \
        $(common_SOURCES) \
        $(event_SOURCES) \
@@ -153,6 +161,7 @@ rm_tests_SOURCES = \
        $(top_srcdir)/src/file/pipe.c \
        $(top_srcdir)/src/file/tmp.c \
        $(top_srcdir)/src/opt/filter.c \
+       $(top_srcdir)/src/recur.c \
        $(top_srcdir)/src/usage.c
 
 rm_tests_CPPFLAGS = $(AM_CPPFLAGS) \
@@ -177,3 +186,11 @@ usage_tests_SOURCES = \
 usage_tests_CPPFLAGS = $(AM_CPPFLAGS) \
        -DARGS_SRC_FILE="$(top_srcdir)/src/args.c" \
        -DUSAGE_SRC_FILE="$(top_srcdir)/src/usage.c"
+
+validate_tests_SOURCES = \
+       $(common_SOURCES) \
+       $(event_SOURCES) \
+       validate.tests.c \
+       $(top_srcdir)/src/file/open.c \
+       $(top_srcdir)/src/file/line.c \
+       $(top_srcdir)/src/validate.c
index b34370a193894a1bf3a15e174b53b4cd98844e5e..14db545bb8acac6a5aa9b2e5cd3b9c76c8eac925 100644 (file)
@@ -71,7 +71,7 @@ static void add_time_set_basic_test() {
 
        assert(1==add_time_set(&ev,"2022-09-01"));
 
-       assert(mktime(&(ev.datetime))==1662019200);
+       assert(mktime(&(ev.datetime))==1662015600);
 }
 
 static void add_to_file_basic_test() {
@@ -126,7 +126,7 @@ static void add_to_file_basic_test() {
 
        memset(buf,0,1000);
        assert(fread(buf,1,1000,fp)==73);
-       assert(strcmp(buf,"2022-06-01 20:00:00 +0000:event3:place\n2022-08-01:name\n2022-09-01:event2\n")==0);
+       assert(strcmp(buf,"2022-06-01 20:00:00 -0700:event3:place\n2022-08-01:name\n2022-09-01:event2\n")==0);
 
        assert(fclose(fp)==0);
 
index 41da3da98dd6ef9f03a4158418d738e6acf5d1de..ea2a67df30372f279c553341535fe29f5cf34cd3 100644 (file)
@@ -19,6 +19,7 @@ static void args_postpone_basic_test();
 static void args_prune_basic_test();
 static void args_rm_basic_test();
 static void args_short_opts_basic_test();
+static void args_validate_basic_test();
 
 int main() {
        setup_env();
@@ -57,6 +58,7 @@ static void args_basic_test() {
        args_postpone_basic_test();
        args_prune_basic_test();
        args_rm_basic_test();
+       args_validate_basic_test();
 
        args_short_opts_basic_test();
        args_long_opts_basic_test();
@@ -154,7 +156,7 @@ static void args_ls_end_date_basic_test() {
        };
        assert(SUB_COMMAND_LS==args(4,ls_end_date_short_args));
        assert(global_options.event_filter.start==0);
-       assert(global_options.event_filter.end==1114934400);
+       assert(global_options.event_filter.end==1114930800);
        optind = 0;
 
        reset_env();
@@ -389,3 +391,15 @@ static void args_short_opts_basic_test() {
 
        reset_env();
 }
+
+static void args_validate_basic_test() {
+       char *validate_args[] = {
+               "ev",
+               "validate",
+               NULL
+       };
+
+       assert(SUB_COMMAND_VALIDATE==args(2,validate_args));
+
+       reset_env();
+}
index 09ef926acc6a9fe413f85eeca55c1b71a088b767..9fb161e0be14338f7a5245a1eb082f73094d3f58 100644 (file)
@@ -6,6 +6,7 @@ int main();
 static void event_init_basic_test();
 static void event_name_set_basic_test();
 static void event_parse_basic_test();
+static void event_parse_missing_name_test();
 static void event_place_set_basic_test();
 static void event_serialize_basic_test();
 static void event_serialize_parse_exactness_test();
@@ -21,6 +22,7 @@ int main() {
        event_time_compare_basic_test();
        event_name_set_basic_test();
        event_parse_basic_test();
+       event_parse_missing_name_test();
        event_place_set_basic_test();
        event_serialize_basic_test();
        event_serialize_parse_exactness_test();
@@ -75,7 +77,7 @@ static void event_parse_basic_test() {
        time_unset(&(ev1.options.until));
        assert(strcmp(ev1.name,"test event")==0);
        assert(strcmp(ev1.place,"test place")==0);
-       assert(mktime(&(ev1.datetime))==1662019200);
+       assert(mktime(&(ev1.datetime))==1662015600);
 
        event_init(&ev2);
        char ex2[] = "2022-09-02:\"test: event2\":\"test: place2\"";
@@ -85,7 +87,7 @@ static void event_parse_basic_test() {
        time_unset(&(ev2.options.until));
        assert(strcmp(ev2.name,"test: event2")==0);
        assert(strcmp(ev2.place,"test: place2")==0);
-       assert(mktime(&(ev2.datetime))==1662105600);
+       assert(mktime(&(ev2.datetime))==1662102000);
        
        event_init(&ev3);
        char ex3[] = "2022-09-03 09:30:00:test event3:test place3";
@@ -95,7 +97,7 @@ static void event_parse_basic_test() {
        time_unset(&(ev3.options.until));
        assert(strcmp(ev3.name,"test event3")==0);
        assert(strcmp(ev3.place,"test place3")==0);
-       assert(mktime(&(ev3.datetime))==1662226200);
+       assert(mktime(&(ev3.datetime))==1662222600);
 
        event_init(&ev4);
        char ex4[] = "2022-09-04 09:30:00 -0700:test event4:test place4";
@@ -105,7 +107,7 @@ static void event_parse_basic_test() {
        time_unset(&(ev4.options.until));
        assert(strcmp(ev4.name,"test event4")==0);
        assert(strcmp(ev4.place,"test place4")==0);
-       assert(mktime(&(ev4.datetime))==1662312600);
+       assert(mktime(&(ev4.datetime))==1662309000);
        
        event_init(&ev5);
        char ex5[] = "[recur:1M]2022-08-04:test event5:test place5";
@@ -115,7 +117,7 @@ static void event_parse_basic_test() {
        time_unset(&(ev5.options.until));
        assert(strcmp(ev5.name,"test event5")==0);
        assert(strcmp(ev5.place,"test place5")==0);
-       assert(mktime(&(ev5.datetime))==1659600000);
+       assert(mktime(&(ev5.datetime))==1659596400);
 
        event_init(&ev6);
        char ex6[] = "[recur:1W]2022-06-05 09:30:00 -0700:test event6:test place6";
@@ -125,27 +127,27 @@ static void event_parse_basic_test() {
        time_unset(&(ev6.options.until));
        assert(strcmp(ev6.name,"test event6")==0);
        assert(strcmp(ev6.place,"test place6")==0);
-       assert(mktime(&(ev6.datetime))==1654450200);
+       assert(mktime(&(ev6.datetime))==1654446600);
 
        event_init(&ev7);
        char ex7[] = "[recur:1W,until:2022-11-01]2022-10-01 09:30:00 -0700:test event7:test place7";
        assert(event_parse(ex7,sizeof(ex7),&ev7)==1);
        assert(ev7.options.recur==1);
        assert(ev7.options.recur_period==TIME_PERIOD_WEEK);
-       assert(mktime(&(ev7.options.until))==1667289600);
+       assert(mktime(&(ev7.options.until))==1667286000);
        assert(strcmp(ev7.name,"test event7")==0);
        assert(strcmp(ev7.place,"test place7")==0);
-       assert(mktime(&(ev7.datetime))==1664645400);
+       assert(mktime(&(ev7.datetime))==1664641800);
 
        event_init(&ev8);
        char ex8[] = "[until:2022-10-10,recur:1W]2022-10-01 09:30:00 -0700:test event8:test place8";
        assert(event_parse(ex8,sizeof(ex8),&ev8)==1);
        assert(ev8.options.recur==1);
        assert(ev8.options.recur_period==TIME_PERIOD_WEEK);
-       assert(mktime(&(ev8.options.until))==1665388800);
+       assert(mktime(&(ev8.options.until))==1665385200);
        assert(strcmp(ev8.name,"test event8")==0);
        assert(strcmp(ev8.place,"test place8")==0);
-       assert(mktime(&(ev8.datetime))==1664645400);
+       assert(mktime(&(ev8.datetime))==1664641800);
 
        event_init(&ev9);
        char ex9[] = "2022-08-01:test";
@@ -155,7 +157,7 @@ static void event_parse_basic_test() {
        time_unset(&(ev9.options.until));
        assert(strcmp(ev9.name,"test")==0);
        assert(NULL==ev9.place);
-       assert(mktime(&(ev9.datetime))==1659340800);
+       assert(mktime(&(ev9.datetime))==1659337200);
 
        event_free(&ev1);
        event_free(&ev2);
@@ -168,6 +170,16 @@ static void event_parse_basic_test() {
        event_free(&ev9);
 }
 
+static void event_parse_missing_name_test() {
+       struct event ev;
+
+       event_init(&ev);
+       char ex[] = "2022-08-01";
+       assert(event_parse(ex,sizeof(ex),&ev)==-1);
+
+       event_free(&ev);
+}
+
 static void event_place_set_basic_test() {
        struct event ev;
 
@@ -205,11 +217,18 @@ static void event_serialize_basic_test() {
        assert(strcmp(buf,"2022-07-01 08:01:15 -0100:event:place\n")==0);
        
        event_init(&ev);
-       assert(1==event_time_set(&(ev.datetime),"2022-07-01 08:01:15 -0100"));
+       assert(1==event_time_set(&(ev.datetime),"2022-07-01 08:01:15 -0700"));
        assert(1==event_name_set(&ev,"event: what?"));
        assert(1==event_place_set(&ev,"place: here"));
        assert(1==event_serialize(buf,EVENT_SERIALIZE_MAX_LENGTH,&ev));
-       assert(strcmp(buf,"2022-07-01 08:01:15 -0100:\"event: what?\":\"place: here\"\n")==0);
+       assert(strcmp(buf,"2022-07-01 08:01:15 -0700:\"event: what?\":\"place: here\"\n")==0);
+
+       event_init(&ev);
+       assert(1==event_time_set(&(ev.datetime),"2022-07-01 08:01:15 +2300"));
+       assert(1==event_name_set(&ev,"event: what?"));
+       assert(1==event_place_set(&ev,"place: here"));
+       assert(1==event_serialize(buf,EVENT_SERIALIZE_MAX_LENGTH,&ev));
+       assert(strcmp(buf,"2022-07-01 08:01:15 +2300:\"event: what?\":\"place: here\"\n")==0);
 
        event_init(&ev);
        assert(1==event_time_set(&(ev.datetime),"2022-06-21"));
@@ -262,7 +281,7 @@ static void event_time_compare_basic_test() {
        char timebuf[40];
        struct event ev;
        time_t timet;
-       struct tm *now, got;
+       struct tm *now;
 
        event_init(&ev);
 
@@ -272,11 +291,7 @@ static void event_time_compare_basic_test() {
        assert(strftime(timebuf,40,"%Y-%m-%d %H:%M:%S %z",now)==25);
        assert(1==event_time_set(&(ev.datetime),timebuf));
 
-       /* daylight savings time set here for some reason.
-        * resetting timet to be time set in ev...
-        */
-       memcpy(&got,&(ev.datetime),sizeof(struct tm));
-       timet = mktime(&got);
+       timet = mktime(&(ev.datetime));
 
        timet -= 1000;
        assert(1==event_time_compare(&(ev.datetime),timet));
@@ -309,8 +324,6 @@ static void event_time_set_basic_test() {
        assert(ev.datetime.tm_year==99);
        assert(ev.datetime.tm_wday==0);
        assert(ev.datetime.tm_yday==58);
-       assert(ev.datetime.tm_isdst==0);
-       assert(ev.datetime.tm_gmtoff==0);
 
        assert(1==event_time_set(&(ev.datetime),"1997-01-28 not a time"));
        assert(ev.datetime.tm_sec==0);
@@ -321,8 +334,6 @@ static void event_time_set_basic_test() {
        assert(ev.datetime.tm_year==97);
        assert(ev.datetime.tm_wday==2);
        assert(ev.datetime.tm_yday==27);
-       assert(ev.datetime.tm_isdst==0);
-       assert(ev.datetime.tm_gmtoff==0);
 
        assert(1==event_time_set(&(ev.datetime),"2002-05-24 121212"));
        assert(ev.datetime.tm_sec==0);
@@ -333,8 +344,6 @@ static void event_time_set_basic_test() {
        assert(ev.datetime.tm_year==102);
        assert(ev.datetime.tm_wday==5);
        assert(ev.datetime.tm_yday==143);
-       assert(ev.datetime.tm_isdst==0);
-       assert(ev.datetime.tm_gmtoff==0);
        
        assert(1==event_time_set(&(ev.datetime),"2012-12-22 12:1212"));
        assert(ev.datetime.tm_sec==0);
@@ -345,8 +354,6 @@ static void event_time_set_basic_test() {
        assert(ev.datetime.tm_year==112);
        assert(ev.datetime.tm_wday==6);
        assert(ev.datetime.tm_yday==356);
-       assert(ev.datetime.tm_isdst==0);
-       assert(ev.datetime.tm_gmtoff==0);
        
        assert(1==event_time_set(&(ev.datetime),"2022-01-24 09:19:55"));
        assert(ev.datetime.tm_sec==55);
@@ -357,8 +364,6 @@ static void event_time_set_basic_test() {
        assert(ev.datetime.tm_year==122);
        assert(ev.datetime.tm_wday==1);
        assert(ev.datetime.tm_yday==23);
-       assert(ev.datetime.tm_isdst==0);
-       assert(ev.datetime.tm_gmtoff==0);
        
        assert(1==event_time_set(&(ev.datetime),"2009-01-03 13:25:25 -0800"));
        assert(ev.datetime.tm_sec==25);
@@ -369,8 +374,18 @@ static void event_time_set_basic_test() {
        assert(ev.datetime.tm_year==109);
        assert(ev.datetime.tm_wday==6);
        assert(ev.datetime.tm_yday==2);
-       assert(ev.datetime.tm_isdst==0);
        assert(ev.datetime.tm_gmtoff==-28800);
+
+       assert(1==event_time_set(&(ev.datetime),"2008-02-07 04:25:16 -0300"));
+       assert(ev.datetime.tm_sec==16);
+       assert(ev.datetime.tm_min==25);
+       assert(ev.datetime.tm_hour==4);
+       assert(ev.datetime.tm_mday==7);
+       assert(ev.datetime.tm_mon==1);
+       assert(ev.datetime.tm_year==108);
+       assert(ev.datetime.tm_wday==4);
+       assert(ev.datetime.tm_yday==37);
+       assert(ev.datetime.tm_gmtoff==-10800);
 }
 
 static void time_unset(struct tm *tm) {
index 61d4f93fd88472bba154d0e1f6c1497214aafc60..951947a5a279c768d7dc31bfbc5d0bba8758c7b3 100644 (file)
@@ -6,9 +6,11 @@
 
 int main();
 static void event_print_basic_test();
+static void event_print_timezone_test();
 
 int main() {
        event_print_basic_test();
+       event_print_timezone_test();
 
        return EXIT_SUCCESS;
 }
@@ -26,3 +28,49 @@ static void event_print_basic_test() {
 
        event_free(&ev);
 }
+
+static void event_print_timezone_test() {
+       struct event ev;
+       char buf[200];
+       FILE *fp;
+
+       char tempfile[] = "/tmp/XXXXXX";
+       fp = file_temp(tempfile);
+       assert(fp!=NULL);
+       assert(fclose(fp)==0);
+
+       fp = NULL;
+
+       event_init(&ev);
+
+       assert(1==event_name_set(&ev,"correct timezone"));
+       assert(1==event_time_set(&(ev.datetime),"2022-07-01 09:39:34"));
+
+       fp = freopen(tempfile,"w",stdout);
+       assert(fp!=NULL);
+
+       assert(1==event_print(&ev));
+
+       event_free(&ev);
+       event_init(&ev);
+
+       assert(1==event_name_set(&ev,"timezone test"));
+       assert(1==event_time_set(&(ev.datetime),"2022-08-01 20:30:15 -0300"));
+       
+       assert(1==event_print(&ev));
+       event_free(&ev);
+
+       assert(fclose(fp)==0);
+
+       memset(buf,0,200);
+
+       fp = NULL;
+       fp = fopen(tempfile,"r");
+       assert(fp!=NULL);
+
+       assert(fread(buf,1,200,fp)==111);
+       assert(memcmp(buf,"2022-07-01 09:39:34 \tcorrect timezone \x1B[31m[OVERDUE]\x1B[0m\n2022-08-01 16:30:15 \ttimezone test \x1B[31m[OVERDUE]\x1B[0m\n",111)==0);
+
+       assert(fclose(fp)==0);
+       assert(remove(tempfile)==0);
+}
index 0124f01b9fa8e29fd96da39794b360d502533c18..74bbf17401814072842ab6e401dd67bf15500a61 100644 (file)
@@ -31,7 +31,7 @@ static void opt_event_filter_date_set_basic_test() {
        assert(global_options.event_filter.start==1230969600);
 
        assert(1==opt_event_filter_date_set(&(global_options.event_filter.end),"2022-08-22"));
-       assert(global_options.event_filter.end==1661155200);
+       assert(global_options.event_filter.end==1661151600);
 
        reset_env();
 }
index 64a2d5fc3a5553493f46dd3fd5ff705b44730117..886dbcca98402d5def2351e499161c2a267a3853 100644 (file)
@@ -54,7 +54,7 @@ static void handle_args_basic_test() {
 
        assert(handle_args(4,args_with_date,&offset,&start_time)==1);
        assert(offset==1);
-       assert(start_time==1585123200);
+       assert(start_time==1585119600);
 
        char *args_with_date_and_postpone[] = {
                "ev",
@@ -67,7 +67,7 @@ static void handle_args_basic_test() {
 
        assert(handle_args(5,args_with_date_and_postpone,&offset,&start_time)==1);
        assert(offset==2);
-       assert(start_time==1585123200);
+       assert(start_time==1585119600);
 
        assert(strcmp(postpone_offset_string,"2W")==0);
 
index 9d91c586c3c6091fd7cbe729d1848014be113033..4bcce8e6ce25214164fc9bb5bf90d76ba9b9d8bd 100644 (file)
@@ -4,11 +4,13 @@
 
 int main();
 static void prune_basic_test();
+static void prune_recur_test();
 
 int main() {
        setup_env();
 
        prune_basic_test();
+       prune_recur_test();
 
        clean_env();
 
@@ -69,3 +71,52 @@ static void prune_basic_test() {
 
        reset_env();
 }
+
+static void prune_recur_test() {
+       char buf[EVENT_SERIALIZE_MAX_LENGTH];
+       char got[EVENT_SERIALIZE_MAX_LENGTH];
+       char timebuf[40];       
+       struct tm curr, *now;
+       time_t now_timet;
+       FILE *src;
+
+       now_timet = time(NULL);
+       now = localtime(&now_timet);
+
+       src = fopen(global_options.file,"w");
+       assert(src!=NULL);
+
+       memset(buf,0,EVENT_SERIALIZE_MAX_LENGTH);
+       memset(timebuf,0,40);
+
+       memcpy(&curr,now,sizeof(struct tm));
+       curr.tm_year -= 1;
+
+       assert(strftime(timebuf,20,"%Y-%m-%d",&curr)==10);
+       for(size_t i=0;i<10;i++) {
+               memset(buf,0,EVENT_SERIALIZE_MAX_LENGTH);
+               snprintf(buf,EVENT_SERIALIZE_MAX_LENGTH,"[recur:2Y]%s:test%lu\n",timebuf,i);
+               
+               assert(fwrite(buf,1,strlen(buf),src)==27);
+       }
+
+       curr.tm_year += 2;
+       assert(strftime(timebuf,20,"%Y-%m-%d",&curr)==10);
+       
+       assert(fclose(src)==0);
+       
+       assert(prune()==EXIT_SUCCESS);
+       
+       src = fopen(global_options.file,"r");
+       assert(src!=NULL);
+       
+       assert(fread(got,1,EVENT_SERIALIZE_MAX_LENGTH,src)==270);
+
+       memset(buf,0,EVENT_SERIALIZE_MAX_LENGTH);
+       sprintf(buf,"[recur:2Y]%s:test0\n[recur:2Y]%s:test1\n[recur:2Y]%s:test2\n[recur:2Y]%s:test3\n[recur:2Y]%s:test4\n[recur:2Y]%s:test5\n[recur:2Y]%s:test6\n[recur:2Y]%s:test7\n[recur:2Y]%s:test8\n[recur:2Y]%s:test9\n",timebuf,timebuf,timebuf,timebuf,timebuf,timebuf,timebuf,timebuf,timebuf,timebuf);
+       assert(memcmp(got,buf,170)==0);
+       
+       assert(fclose(src)==0);
+
+       reset_env();
+}
diff --git a/test/unit/recur.tests.c b/test/unit/recur.tests.c
new file mode 100644 (file)
index 0000000..e744d60
--- /dev/null
@@ -0,0 +1,49 @@
+#include<test_utils.h>
+
+#include<recur.h>
+
+int main();
+static void recur_basic_test();
+
+int main() {
+       setup_env();
+
+       recur_basic_test();
+
+       clean_env();
+
+       return EXIT_SUCCESS;
+}
+
+static void recur_basic_test() {
+       struct event ev;
+       struct tm *target;
+       time_t target_timet;
+
+       event_init(&ev);
+
+       assert(event_name_set(&ev,"test event")==1);
+       assert(event_time_set(&(ev.datetime),"2020-05-13")==1);
+
+       assert(recur(&ev)==0);
+
+       ev.options.recur = 1;
+       ev.options.recur_period = -1;
+       assert(recur(&ev)==-1);
+
+       ev.options.recur_period = TIME_PERIOD_MONTH;
+       target_timet = 1585850345; // ~2020-04-02
+       target = localtime(&target_timet);
+       memcpy(&(ev.options.until),target,sizeof(struct tm));
+
+       assert(recur(&ev)==0);
+
+       memset(&(ev.options.until),0,sizeof(struct tm));
+       assert(recur(&ev)==1);
+
+       assert(1594623600==mktime(&(ev.datetime)));
+
+       event_free(&ev);
+
+       reset_env();
+}
index 4c10ced083badc8ce55ef280f3b0b88f5330376c..9e671dd582a8cc1b9f8628f4f338158927589080 100644 (file)
@@ -6,7 +6,9 @@
 
 int main();
 static void check_need_readd_basic_test();
+static void check_need_readd_month_boundary_test();
 static void check_need_readd_until_test();
+static void check_need_readd_year_boundary_test();
 static void handle_args_basic_test();
 static void rm_basic_test();
 static void rm_dismiss_basic_test();
@@ -18,7 +20,9 @@ int main() {
 
        rm_basic_test();
        check_need_readd_basic_test();
+       check_need_readd_month_boundary_test();
        check_need_readd_until_test();
+       check_need_readd_year_boundary_test();
        rm_dismiss_basic_test();
 
        clean_env();
@@ -68,6 +72,36 @@ static void check_need_readd_basic_test() {
        reset_env();
 }
 
+static void check_need_readd_month_boundary_test() {
+       char buf[EVENT_SERIALIZE_MAX_LENGTH];
+       struct event ev;
+       FILE *src;
+
+       event_init(&ev);
+
+       src = fopen(global_options.file,"w");
+       assert(src!=NULL);
+
+       assert(event_name_set(&ev,"test month boundary")==1);
+       assert(event_time_set(&(ev.datetime),"2021-01-30")==1);
+
+       ev.options.recur = 1;
+       ev.options.recur_period = TIME_PERIOD_WEEK;
+
+       assert(1==check_need_readd(&ev));
+       
+       src = fopen(global_options.file,"r");
+       assert(src!=NULL);
+       
+       memset(buf,0,EVENT_SERIALIZE_MAX_LENGTH);
+       assert(fread(buf,1,EVENT_SERIALIZE_MAX_LENGTH,src)==41);
+       assert(memcmp(buf,"[recur:1W]2021-02-06:test month boundary\n",41)==0);
+       
+       assert(fclose(src)==0);
+
+       reset_env();
+}
+
 static void check_need_readd_until_test() {
        char buf[EVENT_SERIALIZE_MAX_LENGTH];
        struct event ev;
@@ -129,6 +163,36 @@ static void check_need_readd_until_test() {
        reset_env();
 }
 
+static void check_need_readd_year_boundary_test() {
+       char buf[EVENT_SERIALIZE_MAX_LENGTH];
+       struct event ev;
+       FILE *src;
+
+       event_init(&ev);
+
+       src = fopen(global_options.file,"w");
+       assert(src!=NULL);
+
+       assert(event_name_set(&ev,"test year boundary")==1);
+       assert(event_time_set(&(ev.datetime),"2019-01-15")==1);
+
+       ev.options.recur = 1;
+       ev.options.recur_period = TIME_PERIOD_YEAR;
+
+       assert(1==check_need_readd(&ev));
+       
+       src = fopen(global_options.file,"r");
+       assert(src!=NULL);
+       
+       memset(buf,0,EVENT_SERIALIZE_MAX_LENGTH);
+       assert(fread(buf,1,EVENT_SERIALIZE_MAX_LENGTH,src)==40);
+       assert(memcmp(buf,"[recur:1Y]2020-01-15:test year boundary\n",40)==0);
+       
+       assert(fclose(src)==0);
+
+       reset_env();
+}
+
 static void handle_args_basic_test() {
        unsigned long int offset;
        time_t start_time;
@@ -155,7 +219,7 @@ static void handle_args_basic_test() {
        
        assert(1==handle_args(4,args_with_date,&offset,&start_time));
        assert(offset==2);
-       assert(start_time==1662019200);
+       assert(start_time==1662015600);
 }
 
 static void rm_basic_test() {
index cccc21df0f06f1926cc981b9f3821de04693aebb..4f188a1bb32d6b4aca577a07991895f27db06003 100644 (file)
@@ -24,7 +24,7 @@ void reset_env() {
 }
 
 void setup_env() {
-       assert(setenv("TZ","America/Los_Angeles",1)==0);
+       assert(setenv("TZ",":America/Los_Angeles",1)==0);
        tzset();
 
        srand(time(NULL));
diff --git a/test/unit/validate.tests.c b/test/unit/validate.tests.c
new file mode 100644 (file)
index 0000000..5d0e4e0
--- /dev/null
@@ -0,0 +1,45 @@
+#include<test_utils.h>
+
+#include<validate.h>
+
+int main();
+static void validate_basic_test();
+
+int main() {
+       setup_env();
+
+       validate_basic_test();
+
+       clean_env();
+
+       return EXIT_SUCCESS;
+}
+
+static void validate_basic_test(){
+       char buf[1000];
+       FILE *fp;
+
+       memset(buf,0,1000);
+
+       fp = fopen(global_options.file,"w");
+       assert(fp!=NULL);
+
+       strcpy(buf,"2022-08-01:test\n2022-08-02\n");
+       assert(fwrite(buf,1,27,fp)==27);
+       assert(fclose(fp)==0);
+
+       assert(validate()==EXIT_FAILURE);
+
+       reset_env();
+       
+       fp = fopen(global_options.file,"w");
+       assert(fp!=NULL);
+       
+       strcpy(buf,"2022-08-01:test\n2022-08-02:test2\n");
+       assert(fwrite(buf,1,33,fp)==33);
+       assert(fclose(fp)==0);
+
+       assert(validate()==EXIT_SUCCESS);
+
+       reset_env();
+}