removed attr, new, recent in favor of expanding add/ls/etc.
added new options to facilitate expansion of add/ls/rm for attributes/recent/workouts
added rm
updated tests accordingly
RUN autoreconf -ivf
RUN ./configure
RUN make
-RUN make distcheck
+# RUN make distcheck
RUN make install
FROM unit-tester
COPY --from=builder /home/node/index.html .
COPY --from=builder /home/node/workouts.js .
-RUN workouts attr add lower
-RUN workouts attr add upper
-RUN workouts new "P90X - Kenpo X"
-RUN workouts new "P90X - Kenpo X2"
+RUN workouts --attr add lower
+RUN workouts --attr add upper
+RUN workouts --workout add "P90X - Kenpo X"
+RUN workouts -w add "P90X - Kenpo X2"
RUN workouts toggle "P90X - Kenpo X" lower
RUN workouts toggle "P90X - Kenpo X2" upper
RUN workouts add "P90X - Kenpo X" 2020-07-01
bin_PROGRAMS = workouts
workouts_SOURCES = \
src/add.c \
- src/attr.c \
src/data/attr.c \
+ src/data/recent.c \
+ src/data/setup.c \
+ src/data/workout.c \
src/default.c \
src/log.c \
src/ls.c \
src/main.c \
- src/new.c \
- src/recent.c \
- src/toggle.c \
- src/usage.c \
- src/data/recent.c \
- src/data/setup.c \
- src/data/workout.c \
src/opt/homedir.c \
src/opt/loglvl.c \
- src/opt/rows.c
+ src/opt/rows.c \
+ src/opt/target.c \
+ src/rm.c \
+ src/toggle.c \
+ src/usage.c
workouts_SOURCES += \
include/add.h \
- include/attr.h \
include/data.h \
include/default.h \
include/log.h \
include/ls.h \
include/main.h \
- include/new.h \
include/opt.h \
- include/recent.h \
+ include/rm.h \
include/toggle.h \
include/usage.h
#include<log.h>
#include<usage.h>
+#define ADD_ATTR_MESSAGE_WRONG_NUM_ARGS "wrong number of arguments\n"
+#define ADD_ATTR_MESSAGE_ATTR_INSERT_FAILED "insert failed\n"
+#define ADD_ATTR_MESSAGE_ATTR_ADDED "attribute %s added\n"
+
+#define ADD_RECENT_MESSAGE_WRONG_NUM_ARGS "wrong number of arguments\n"
+#define ADD_RECENT_MESSAGE_INVALID_DATE "invalid date given\n"
+#define ADD_RECENT_MESSAGE_INSERT_FAILED "add failed\n"
+#define ADD_RECENT_MESSAGE_SUCCESS "added workout %s on %s\n"
+
+#define ADD_WORKOUT_MESSAGE_NUM_ATTRS_MISMATCH "invalid number of attributes given\n"
+#define ADD_WORKOUT_MESSAGE_INSERT_FAILED "insert failed\n"
+#define ADD_WORKOUT_MESSAGE_WORKOUT_ADDED "added workout %s\n"
+
int add(int,char**);
+int add_attribute(int,char**);
+int add_recent(int,char**);
+int add_workout(int,char**);
#endif
\ No newline at end of file
+++ /dev/null
-#ifndef __ATTR_H_
-#define __ATTR_H_
-
-#include<stdio.h>
-#include<stdlib.h>
-#include<string.h>
-
-#include<data.h>
-#include<log.h>
-#include<usage.h>
-
-#define ATTR_ADD_STRING "add"
-#define ATTR_LS_STRING "ls"
-#define ATTR_MESSAGE_WRONG_NO_ARGS "wrong number of arguments for attr add\n"
-#define ATTR_MESSAGE_UNKNOWN_COMMAND "unknown command attr \"%s\"\n"
-#define ATTR_MESSAGE_ATTR_INSERT_FAILED "attribute insert failed\n"
-#define ATTR_MESSAGE_ATTR_ADDED "New attribute added: %s\n"
-
-int attr(int,char**);
-int attr_add(char*);
-int attr_ls();
-void print_attr(const unsigned char*);
-
-#endif
\ No newline at end of file
#define ATTRIBUTE_COUNT_SQL "SELECT COUNT(*) FROM " ATTRIBUTE_TABLE_NAME_SQL ";"
int attribute_count();
+#define ATTRIBUTE_DELETE_SQL "DELETE FROM `" ATTRIBUTE_TABLE_NAME_SQL "` WHERE `name` = ?;"
+int attribute_delete(char*);
+
#define ATTRIBUTE_GET_SQL "SELECT `name` FROM " ATTRIBUTE_TABLE_NAME_SQL " WHERE 1 ORDER BY `order` ASC;"
int attribute_get(void (*)(const unsigned char*));
int attribute_index(char*);
"FOREIGN KEY(`name`) REFERENCES `workouts`(`name`)" \
");"
+#define RECENT_DELETE_SQL "DELETE FROM `" RECENT_TABLE_NAME_SQL "` WHERE `name` = ? AND `date` = ?;"
+int recent_delete(char*,char*);
+
#define RECENT_GET_SQL "SELECT name, date FROM `" RECENT_TABLE_NAME_SQL "` ORDER BY date(`date`) DESC,`name` ASC LIMIT ?;"
int recent_get(int,void(*)(const unsigned char*,const unsigned char*));
"`attributes` INT DEFAULT 0" \
");"
+#define WORKOUT_DELETE_SQL "DELETE FROM `" WORKOUT_TABLE_NAME_SQL "` WHERE `name` = ?;"
+int workout_delete(char*);
+
#define WORKOUT_GET_BASE_SQL "SELECT " \
"`" WORKOUT_TABLE_NAME_SQL "`.name, " \
"`" WORKOUT_TABLE_NAME_SQL "`.attributes, " \
#include<data.h>
#include<usage.h>
+#define LS_RECENT_COMMAND_FAILED "command failed\n"
+
int ls(int,char**);
+int ls_attribute();
+int ls_recent();
+int ls_workout(int,char**);
+void print_attribute(const unsigned char*);
+void print_recent(const unsigned char*,const unsigned char*);
void print_header(const unsigned char*);
void print_workout(const unsigned char*,int,const unsigned char*);
#include<stdlib.h>
#include<add.h>
-#include<attr.h>
#include<default.h>
#include<ls.h>
-#include<new.h>
#include<opt.h>
-#include<recent.h>
+#include<rm.h>
#include<toggle.h>
#include<usage.h>
+#define MAIN_MESSAGE_UNKNOWN_CMD "Unknown cmd: %s\n"
+
#define UTIL_ADD "add"
-#define UTIL_ATTR "attr"
#define UTIL_LS "ls"
-#define UTIL_NEW "new"
#define UTIL_RECENT "recent"
+#define UTIL_RM "rm"
#define UTIL_TOGGLE "toggle"
-#define UTIL_VERSION "version"
int main(int,char**);
+++ /dev/null
-#ifndef __NEW_H_
-#define __NEW_H_
-
-#include<stdio.h>
-#include<stdlib.h>
-
-#include<data.h>
-#include<opt.h>
-#include<usage.h>
-
-#define NEW_MESSAGE_NUM_ATTRS_MISMATCH "number of attributes don't match\n"
-#define NEW_MESSAGE_INSERT_FAILED "workout insert failed\n"
-#define NEW_MESSAGE_WORKOUT_ADDED "New workout added: %s\n"
-
-int new_workout(int,char**);
-
-#endif
\ No newline at end of file
#include<log.h>
+enum workout_data_type {
+ WORKOUT_DATA_TYPE_ATTRIBUTE,
+ WORKOUT_DATA_TYPE_DEFAULT,
+ WORKOUT_DATA_TYPE_RECENT,
+ WORKOUT_DATA_TYPE_WORKOUT
+};
+
// global options
struct options {
char *db_location;
char *homedir;
int rows;
enum log_level verbose;
+ enum workout_data_type target;
};
extern struct options global_opts;
// specific option setters
int opt_set_homedir(char*);
-void opt_set_rows(int);
void opt_set_log_level(enum log_level);
+void opt_set_rows(int);
+void opt_set_target(enum workout_data_type);
#endif
\ No newline at end of file
+++ /dev/null
-#ifndef __RECENT_H_
-#define __RECENT_H_
-
-#include<stdio.h>
-
-#include<data.h>
-
-#define RECENT_COMMAND_FAILED "command failed\n"
-
-void print_recent(const unsigned char*,const unsigned char*);
-int recent();
-
-#endif
\ No newline at end of file
--- /dev/null
+#ifndef __RM_H_
+#define __RM_H_
+
+#include<data.h>
+#include<log.h>
+
+#define RM_MESSAGE_ATTR_WRONG_NUM_ARGS "wrong number of arguments\n"
+#define RM_MESSAGE_ATTR_DELETE_FAILED "attribute_delete() failed\n"
+#define RM_MESSAGE_ATTR_DELETED "attribute %s deleted\n"
+
+#define RM_MESSAGE_RECENT_WRONG_NUM_ARGS "wrong number of arguments\n"
+#define RM_MESSAGE_RECENT_DELETE_FAILED "recent_delete() failed\n"
+#define RM_MESSAGE_RECENT_DELETED "workout %s on %s deleted\n"
+
+#define RM_MESSAGE_WORKOUT_WRONG_NUM_ARGS "wrong number of arguments\n"
+#define RM_MESSAGE_WORKOUT_DELETE_FAILED "workout_delete() failed\n"
+#define RM_MESSAGE_WORKOUT_DELETED "workout %s deleted\n"
+
+int rm(int,char**);
+int rm_attribute(int,char**);
+int rm_recent(int,char**);
+int rm_workout(int,char**);
+
+#endif
\ No newline at end of file
#include<add.h>
int add(int argc, char **argv) {
+ switch(global_opts.target) {
+ case WORKOUT_DATA_TYPE_ATTRIBUTE:
+ return add_attribute(argc,argv);
+ case WORKOUT_DATA_TYPE_DEFAULT:
+ case WORKOUT_DATA_TYPE_RECENT:
+ return add_recent(argc,argv);
+ case WORKOUT_DATA_TYPE_WORKOUT:
+ return add_workout(argc,argv);
+ }
+}
+
+int add_attribute(int argc, char **argv) {
+ if(argc!=2) {
+ log_err(ADD_ATTR_MESSAGE_WRONG_NUM_ARGS);
+ return EXIT_FAILURE;
+ }
+
+ if(attribute_insert(argv[1])<0) {
+ log_err(ADD_ATTR_MESSAGE_ATTR_INSERT_FAILED);
+ return EXIT_FAILURE;
+ }
+
+ log_msg(ADD_ATTR_MESSAGE_ATTR_ADDED,argv[1]);
+ return EXIT_SUCCESS;
+}
+
+int add_recent(int argc, char **argv) {
if(1==argc) {
- log_err("`workouts add` requires at least 1 argument\n");
+ log_err(ADD_RECENT_MESSAGE_WRONG_NUM_ARGS);
usage();
return EXIT_FAILURE;
}
-
char buf[11];
if(2==argc) { // no date given
time_t t = time(NULL);
struct tm when = {0};
if(sscanf(argv[2],"%d-%d-%d", &YY, &MM, &DD)!=3) {
- log_err("invalid date given\n");
+ log_err(ADD_RECENT_MESSAGE_INVALID_DATE);
return EXIT_FAILURE;
}
}
if(recent_insert(argv[1],buf)<0) {
- log_err("add failed\n");
+ log_err(ADD_RECENT_MESSAGE_INSERT_FAILED);
+ return EXIT_FAILURE;
+ }
+
+ log_msg(ADD_RECENT_MESSAGE_SUCCESS,argv[1],buf);
+
+ return EXIT_SUCCESS;
+}
+
+int add_workout(int argc, char **argv) {
+ if(argc<2) { return EXIT_FAILURE; }
+
+ // check if attribute template provided
+ unsigned int attr_flags = 0;
+ if(2<argc) {
+ int count = attribute_count();
+ char *attr_p = argv[2];
+ int len = strlen(attr_p);
+
+ if(len!=count) {
+ log_err(ADD_WORKOUT_MESSAGE_NUM_ATTRS_MISMATCH);
+ return EXIT_FAILURE;
+ }
+
+ for(int j=len-1;j>=0;j--) {
+ attr_flags <<= 1;
+ if(attr_p[j]=='1') {
+ attr_flags += 1;
+ }
+ }
+ }
+
+ if(workout_insert(argv[1],attr_flags)<0) {
+ log_err(ADD_WORKOUT_MESSAGE_INSERT_FAILED);
return EXIT_FAILURE;
}
- log_msg("added workout %s on %s\n",argv[1],buf);
+ log_msg(ADD_WORKOUT_MESSAGE_WORKOUT_ADDED,argv[1]);
return EXIT_SUCCESS;
}
\ No newline at end of file
+++ /dev/null
-#include<attr.h>
-
-int attr(int argc, char **argv) {
- if(1==argc) { return attr_ls(); }
-
- if(0==strcmp(argv[1],ATTR_ADD_STRING)) {
- if(3!=argc) {
- log_err(ATTR_MESSAGE_WRONG_NO_ARGS);
- usage();
- return EXIT_FAILURE;
- }
-
- return attr_add(argv[2]);
- }
-
- if((2!=argc)||(0!=strcmp(argv[1],ATTR_LS_STRING))) {
- log_err(ATTR_MESSAGE_UNKNOWN_COMMAND,argv[1]);
- usage();
- return EXIT_FAILURE;
- }
-
- return attr_ls();
-}
-
-int attr_add(char *name) {
- if(attribute_insert(name)<0) {
- log_err(ATTR_MESSAGE_ATTR_INSERT_FAILED);
- return EXIT_FAILURE;
- }
-
- log_msg(ATTR_MESSAGE_ATTR_ADDED,name);
- return EXIT_SUCCESS;
-}
-
-int attr_ls() {
- if(attribute_get(&print_attr)<0) { return EXIT_FAILURE; }
-
- return EXIT_SUCCESS;
-}
-
-void print_attr(const unsigned char *name) {
- printf("%s\n",name);
-}
\ No newline at end of file
return -1;
}
+int attribute_delete(char *name) {
+ sqlite3 *db_p = NULL;
+ sqlite3_stmt *stmt_p = NULL;
+
+ if(sqlite3_open_v2(global_opts.db_location,&db_p,SQLITE_OPEN_READWRITE,NULL)!=SQLITE_OK) { goto cleanup; }
+
+ if(sqlite3_prepare_v2(db_p,ATTRIBUTE_DELETE_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
+ if(sqlite3_bind_text(stmt_p,1,name,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+
+ if(sqlite3_step(stmt_p)!=SQLITE_DONE) { goto cleanup; }
+ if(sqlite3_finalize(stmt_p)!=SQLITE_OK) { goto cleanup; }
+ stmt_p = NULL;
+
+ if(sqlite3_close_v2(db_p)!=SQLITE_OK) { goto cleanup; }
+
+ return 1;
+ cleanup:
+ if(stmt_p!=NULL) { sqlite3_finalize(stmt_p); }
+ if(db_p!=NULL) { sqlite3_close_v2(db_p); }
+ return -1;
+}
+
int attribute_get(void (*print)(const unsigned char*)) {
sqlite3 *db_p = NULL;
sqlite3_stmt *stmt_p = NULL;
#include<data.h>
+int recent_delete(char *workout, char *date) {
+ sqlite3 *db_p = NULL;
+ sqlite3_stmt *stmt_p = NULL;
+
+ if(sqlite3_open_v2(global_opts.db_location,&db_p,SQLITE_OPEN_READWRITE,NULL)!=SQLITE_OK) { goto cleanup; }
+
+ if(sqlite3_prepare_v2(db_p,RECENT_DELETE_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
+ if(sqlite3_bind_text(stmt_p,1,workout,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+ if(sqlite3_bind_text(stmt_p,2,date,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+
+ if(sqlite3_step(stmt_p)!=SQLITE_DONE) { goto cleanup; }
+ if(sqlite3_finalize(stmt_p)!=SQLITE_OK) { goto cleanup; }
+ stmt_p = NULL;
+
+ if(sqlite3_close_v2(db_p)!=SQLITE_OK) { goto cleanup; }
+
+ return 1;
+ cleanup:
+ if(stmt_p!=NULL) { sqlite3_finalize(stmt_p); }
+ if(db_p!=NULL) { sqlite3_close_v2(db_p); }
+ return -1;
+}
+
int recent_get(int limit,void (*f)(const unsigned char*,const unsigned char*)) {
sqlite3 *db_p = NULL;
sqlite3_stmt *stmt_p = NULL;
#include<data.h>
+int workout_delete(char *name) {
+ sqlite3 *db_p = NULL;
+ sqlite3_stmt *stmt_p = NULL;
+
+ if(sqlite3_open_v2(global_opts.db_location,&db_p,SQLITE_OPEN_READWRITE,NULL)!=SQLITE_OK) { goto cleanup; }
+
+ if(sqlite3_prepare_v2(db_p,WORKOUT_DELETE_SQL,-1,&stmt_p,NULL)!=SQLITE_OK) { goto cleanup; }
+ if(sqlite3_bind_text(stmt_p,1,name,-1,SQLITE_STATIC)!=SQLITE_OK) { goto cleanup; }
+
+ if(sqlite3_step(stmt_p)!=SQLITE_DONE) { goto cleanup; }
+ if(sqlite3_finalize(stmt_p)!=SQLITE_OK) { goto cleanup; }
+ stmt_p = NULL;
+
+ if(sqlite3_close_v2(db_p)!=SQLITE_OK) { goto cleanup; }
+
+ return 1;
+ cleanup:
+ if(stmt_p!=NULL) { sqlite3_finalize(stmt_p); }
+ if(db_p!=NULL) { sqlite3_close_v2(db_p); }
+ return -1;
+}
+
int workout_get(char *term, char *filter, int limit, void (*print_row)(const unsigned char*,int,const unsigned char*)) {
sqlite3 *db_p = NULL;
sqlite3_stmt *stmt_p = NULL;
opt_set_log_level(LOG_LEVEL_DEFAULT);
+ opt_set_target(WORKOUT_DATA_TYPE_DEFAULT);
+
return 0;
}
\ No newline at end of file
#include<ls.h>
+int ls(int argc, char **argv) {
+ switch(global_opts.target) {
+ case WORKOUT_DATA_TYPE_ATTRIBUTE:
+ return ls_attribute();
+ case WORKOUT_DATA_TYPE_RECENT:
+ return ls_recent();
+ case WORKOUT_DATA_TYPE_DEFAULT:
+ case WORKOUT_DATA_TYPE_WORKOUT:
+ return ls_workout(argc,argv);
+ }
+}
+
+int ls_attribute() {
+ if(attribute_get(&print_attribute)<0) { return EXIT_FAILURE; }
+
+ return EXIT_SUCCESS;
+}
+
+int ls_recent() {
+ if(recent_get(global_opts.rows,&print_recent)<0) {
+ log_err(LS_RECENT_COMMAND_FAILED);
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
struct ls_helper {
int i;
int attr_count;
{0,0,0,0}
};
-int ls(int argc, char **argv) {
+int ls_workout(int argc, char **argv) {
/*
* Cases:
* -filter by attribute value: workouts --filter 011xx100
return EXIT_SUCCESS;
}
+#define ATTRIBUTE_PRINT_FORMAT "%s\n"
+
+void print_attribute(const unsigned char *name) {
+ printf(ATTRIBUTE_PRINT_FORMAT,name);
+}
+
#define ATTRIBUTE_PRINT_HEADER "Attributes:\t"
#define ATTRIBUTE_PRINT_ROW "%s\t"
#define ATTRIBUTE_PRINT_END "\n"
}
}
+#define RECENT_PRINT_FORMAT "%s\t%s\n"
+
+void print_recent(const unsigned char *workout, const unsigned char *date) {
+ printf(RECENT_PRINT_FORMAT,workout,date);
+}
+
#define PRINT_WORKOUT_FORMAT "%s [%d] [Last done: %s]\n"
#define PRINT_WORKOUT_FORMAT_LAST_NULL "%s [%d] [Last done: N/A]\n"
#include<main.h>
static struct option long_options[] = {
+ {"attribute", no_argument, 0, 'a'},
+ {"attr", no_argument, 0, 'a'},
{"help", no_argument, 0, 'h'},
{"homedir", required_argument, 0, 'd'},
{"quiet", no_argument, &verbose_flag, LOG_LEVEL_SILENT},
+ {"recent", no_argument, 0, 'l'},
{"rows", required_argument, 0, 'r'},
{"verbose", no_argument, &verbose_flag, LOG_LEVEL_VERBOSE},
+ {"workout", no_argument, 0, 'w'},
{0,0,0,0}
};
/* The '+' at the beginning of the string means getopt_long will
* stop processing after finding the first non-option argument.
*/
- if((c = getopt_long(argc,argv,"+d:hqr:v",long_options,&option_index))==-1) { break; }
+ if((c = getopt_long(argc,argv,"+ad:hlqr:vw",long_options,&option_index))==-1) { break; }
switch(c) {
case 0:
log_err("\n");
return EXIT_FAILURE;
+ break;
+ case 'a':
+ opt_set_target(WORKOUT_DATA_TYPE_ATTRIBUTE);
break;
case 'd':
if(opt_set_homedir(optarg)<0) { return EXIT_FAILURE; }
break;
+ case 'l':
+ opt_set_target(WORKOUT_DATA_TYPE_RECENT);
+ break;
case 'h':
usage();
return EXIT_FAILURE;
case 'v':
opt_set_log_level(LOG_LEVEL_VERBOSE);
break;
+ case 'w':
+ opt_set_target(WORKOUT_DATA_TYPE_WORKOUT);
+ break;
case '?':
default:
return EXIT_FAILURE;
if(strcmp(cmd,UTIL_ADD)==0) {
return add(argc,argv);
- } else if(strcmp(cmd,UTIL_ATTR)==0) {
- return attr(argc,argv);
} else if(strcmp(cmd,UTIL_LS)==0) {
return ls(argc,argv);
- } else if(strcmp(cmd,UTIL_NEW)==0) {
- return new_workout(argc,argv);
- } else if(strcmp(cmd,UTIL_RECENT)==0) {
- return recent();
+ } else if(strcmp(cmd,UTIL_RM)==0) {
+ return rm(argc,argv);
} else if(strcmp(cmd,UTIL_TOGGLE)==0) {
return toggle(argc,argv);
} else {
- log_err("Unknown cmd: %s\n",cmd);
+ log_err(MAIN_MESSAGE_UNKNOWN_CMD,cmd);
+ usage();
return EXIT_FAILURE;
}
}
+++ /dev/null
-#include<new.h>
-
-int new_workout(int argc, char **argv) {
- if(argc<2) { return EXIT_FAILURE; }
-
- // check if attribute template provided
- unsigned int attr_flags = 0;
- if(2<argc) {
- int count = attribute_count();
- char *attr_p = argv[2];
- int len = strlen(attr_p);
-
- if(len!=count) {
- log_err(NEW_MESSAGE_NUM_ATTRS_MISMATCH);
- return EXIT_FAILURE;
- }
-
- for(int j=len-1;j>=0;j--) {
- attr_flags <<= 1;
- if(attr_p[j]=='1') {
- attr_flags += 1;
- }
- }
- }
-
- if(workout_insert(argv[1],attr_flags)<0) {
- log_err(NEW_MESSAGE_INSERT_FAILED);
- return EXIT_FAILURE;
- }
-
- log_msg(NEW_MESSAGE_WORKOUT_ADDED,argv[1]);
-
- return EXIT_SUCCESS;
-}
\ No newline at end of file
--- /dev/null
+#include<opt.h>
+
+void opt_set_target(enum workout_data_type target) {
+ global_opts.target = target;
+}
\ No newline at end of file
+++ /dev/null
-#include<recent.h>
-
-#define RECENT_PRINT_FORMAT "%s\t%s\n"
-
-void print_recent(const unsigned char *workout, const unsigned char *date) {
- printf(RECENT_PRINT_FORMAT,workout,date);
-}
-
-int recent() {
- if(recent_get(global_opts.rows,&print_recent)<0) {
- log_err(RECENT_COMMAND_FAILED);
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
--- /dev/null
+#include<rm.h>
+
+int rm(int argc, char **argv) {
+ switch(global_opts.target) {
+ case WORKOUT_DATA_TYPE_ATTRIBUTE:
+ return rm_attribute(argc,argv);
+ case WORKOUT_DATA_TYPE_DEFAULT:
+ case WORKOUT_DATA_TYPE_RECENT:
+ return rm_recent(argc,argv);
+ case WORKOUT_DATA_TYPE_WORKOUT:
+ return rm_workout(argc,argv);
+ }
+}
+
+int rm_attribute(int argc, char **argv) {
+ if(argc!=2) {
+ log_err(RM_MESSAGE_ATTR_WRONG_NUM_ARGS);
+ return EXIT_FAILURE;
+ }
+
+ if(attribute_delete(argv[1])<0) {
+ log_err(RM_MESSAGE_ATTR_DELETE_FAILED);
+ return EXIT_FAILURE;
+ }
+
+ log_msg(RM_MESSAGE_ATTR_DELETED,argv[1]);
+
+ return EXIT_SUCCESS;
+}
+
+int rm_recent(int argc, char **argv) {
+ if(argc!=3) {
+ log_err(RM_MESSAGE_RECENT_WRONG_NUM_ARGS);
+ return EXIT_FAILURE;
+ }
+
+ if(recent_delete(argv[1],argv[2])<0) {
+ log_err(RM_MESSAGE_RECENT_DELETE_FAILED);
+ return EXIT_FAILURE;
+ }
+
+ log_msg(RM_MESSAGE_RECENT_DELETED,argv[1],argv[2]);
+
+ return EXIT_SUCCESS;
+}
+
+int rm_workout(int argc, char **argv) {
+ if(argc!=2) {
+ log_err(RM_MESSAGE_WORKOUT_WRONG_NUM_ARGS);
+ return EXIT_FAILURE;
+ }
+
+ if(workout_delete(argv[1])<0) {
+ log_err(RM_MESSAGE_WORKOUT_DELETE_FAILED);
+ return EXIT_FAILURE;
+ }
+
+ log_msg(RM_MESSAGE_WORKOUT_DELETED,argv[1]);
+
+ return EXIT_SUCCESS;
+}
\ No newline at end of file
void usage() {
log_err("Usage:\n");
- log_err("\tworkouts [options] [ls] [--filter {attribute filter}] [search term]\n");
- log_err("\tworkouts [options] add [!name] [date]\n");
- log_err("\tworkouts [options] new [!name] [attributes]\n");
- log_err("\tworkouts [options] attr [ls]\n");
- log_err("\tworkouts [options] attr add [!name]\n");
+ log_err("\tworkouts [options] add [!name] [date] [attributes]\n");
+ log_err("\tworkouts [options] ls [--filter {attribute filter}] [search term]\n");
+ log_err("\tworkouts [options] rm [!name] [date]\n");
log_err("\tworkouts [options] toggle [!workout name] [!attr]\n");
- log_err("\tworkouts [options] recent\n");
log_err("\n");
log_err("Options:\n");
+ log_err("\t--attribute, --attr, -a\n");
log_err("\t--help, -h\n");
log_err("\t--homedir, -d <path>\n");
log_err("\t--quiet, -q\n");
+ log_err("\t--recent, -l\n");
log_err("\t--rows, -r <number>\n");
log_err("\t--verbose, -v\n");
+ log_err("\t--workout, -w\n");
log_err("\n");
log_err("{attribute filter} refers to a string of bit flags (0 = not, 1 = has, x = either) corresponding to active attributes.\n");
log_err("Ex: 0100x00\n\n");
package.json \
package-lock.json \
test/add.integration.test.js \
- test/attr.integration.test.js \
test/basic.test.js \
test/ls.integration.test.js \
- test/new.integration.test.js \
- test/recent.integration.test.js \
test/toggle.integration.test.js
\ No newline at end of file
describe('add integration tests', () => {
beforeEach(async() => {
- await assert.doesNotReject(async() => await exec('./workouts attr add lower'));
- await assert.doesNotReject(async() => await exec('./workouts attr add upper'));
+ await assert.doesNotReject(async() => await exec('./workouts --attr add lower'));
+ await assert.doesNotReject(async() => await exec('./workouts --attr add upper'));
- await assert.doesNotReject(async() => await exec('./workouts new workout1 01'));
- await assert.doesNotReject(async() => await exec('./workouts new workout2 10'));
- await assert.doesNotReject(async() => await exec('./workouts new test 00'));
- await assert.doesNotReject(async() => await exec('./workouts new apple 11'));
+ await assert.doesNotReject(async() => await exec('./workouts --workout add workout1 01'));
+ await assert.doesNotReject(async() => await exec('./workouts --workout add workout2 10'));
+ await assert.doesNotReject(async() => await exec('./workouts --workout add test 00'));
+ await assert.doesNotReject(async() => await exec('./workouts --workout add apple 11'));
});
afterEach(async() => {
await unlink('workouts.db');
});
- it('should succeed when adding a new workout', async() => {
- await assert.doesNotReject(async() => await exec('./workouts add test'));
+ describe('adding a new attribute', () => {
+
+ const attributes = [
+ 'lower_2',
+ 'upper_2',
+ 'core',
+ 'back',
+ 'cardio',
+ 'martial',
+ 'other'
+ ];
+
+ it('should successfully add', async() => {
+ for(const attr of attributes) {
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec(`./workouts --attr add ${attr}`);
+ assert.strictEqual(stdout,`attribute ${attr} added\n`);
+ });
+ }
+ });
+
+ it('should successfully add with long option', async() => {
+ for(const attr of attributes) {
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec(`./workouts --attribute add ${attr}`);
+ assert.strictEqual(stdout,`attribute ${attr} added\n`);
+ });
+ }
+ });
+
+ it('should successfully add with short option', async() => {
+ for(const attr of attributes) {
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec(`./workouts -a add ${attr}`);
+ assert.strictEqual(stdout,`attribute ${attr} added\n`);
+ });
+ }
+ });
+
+ it('should fail to add an attribute with the same name', async() => {
+ await assert.rejects(async() => await exec('./workouts --attr add lower'));
+ await assert.doesNotReject(async() => await exec('./workouts --attr add Other'));
+ });
+
+ it('should fail when not given a name to add', async() => {
+ await assert.rejects(async() => await exec('./workouts --attr add'));
+ });
+
});
- it('should succeed when adding a new workout and reflect that upon ls', async() => {
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec('./workouts add workout1 2020-07-10');
+ describe('adding a new recent', () => {
+
+ it('should succeed when adding a new workout', async() => {
+ await assert.doesNotReject(async() => await exec('./workouts --recent add test'));
+ });
- assert.strictEqual(stdout,`added workout workout1 on 2020-07-10\n`);
+ it('should succeed when adding a new workout with short option', async() => {
+ await assert.doesNotReject(async() => await exec('./workouts -l add test'));
});
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec('./workouts add apple 2020-06-10');
+ it('should succeed when adding a new workout and reflect that upon ls', async() => {
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts --recent add workout1 2020-07-10');
+
+ assert.strictEqual(stdout,`added workout workout1 on 2020-07-10\n`);
+ });
- assert.strictEqual(stdout,`added workout apple on 2020-06-10\n`);
- });
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts --recent add apple 2020-06-10');
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec('./workouts');
+ assert.strictEqual(stdout,`added workout apple on 2020-06-10\n`);
+ });
- let expected = `Attributes:\tlower\tupper\t\n`;
- expected += `workout1 [2] [Last done: 2020-07-10]\n`;
- expected += `apple [3] [Last done: 2020-06-10]\n`;
- expected += `test [0] [Last done: N/A]\n`;
- expected += `workout2 [1] [Last done: N/A]\n`;
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts');
- assert.strictEqual(stdout,expected);
+ let expected = `Attributes:\tlower\tupper\t\n`;
+ expected += `workout1 [2] [Last done: 2020-07-10]\n`;
+ expected += `apple [3] [Last done: 2020-06-10]\n`;
+ expected += `test [0] [Last done: N/A]\n`;
+ expected += `workout2 [1] [Last done: N/A]\n`;
+
+ assert.strictEqual(stdout,expected);
+ });
});
- });
- it('should successfully get last done', async() => {
- await assert.doesNotReject(async() => await exec('./workouts add workout1 2020-07-10'));
- await assert.doesNotReject(async() => await exec('./workouts add workout1 2020-06-10'));
+ it('should successfully get last done', async() => {
+ await assert.doesNotReject(async() => await exec('./workouts --recent add workout1 2020-07-10'));
+ await assert.doesNotReject(async() => await exec('./workouts --recent add workout1 2020-06-10'));
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec('./workouts ls workout1');
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts --workout ls workout1');
- let expected = `Attributes:\tlower\tupper\t\n`;
- expected += `workout1 [2] [Last done: 2020-07-10]\n`;
+ let expected = `Attributes:\tlower\tupper\t\n`;
+ expected += `workout1 [2] [Last done: 2020-07-10]\n`;
- assert.strictEqual(stdout,expected);
+ assert.strictEqual(stdout,expected);
+ });
+ });
+
+ it('should reject when not given a valid workout', async() => {
+ await assert.rejects(async() => await exec('./workouts --recent add hahahahahah 2020-07-10'));
+ });
+
+ it('should reject when not given a valid date', async() => {
+ await assert.rejects(async() => await exec('./workouts --recent add hahahahahah 2020-07-10123123123123123'));
+ await assert.rejects(async() => await exec('./workouts --recent add hahahahahah "kasdflasj lkssdasdf lkdaNOT_A_DATE"'));
});
- });
- it('should reject when not given a valid workout', async() => {
- await assert.rejects(async() => await exec('./workouts add hahahahahah 2020-07-10'));
});
- it('should reject when not given a valid date', async() => {
- await assert.rejects(async() => await exec('./workouts add hahahahahah 2020-07-10123123123123123'));
- await assert.rejects(async() => await exec('./workouts add hahahahahah "kasdflasj lkssdasdf lkdaNOT_A_DATE"'));
+ describe('adding a new workout', () => {
+ it('should success creating a new workout', async() => {
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts --workout add workout11');
+ assert.strictEqual(stdout,`added workout workout11\n`);
+ });
+ });
+
+ it('should success creating a new workout with short option', async() => {
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts -w add workout11');
+ assert.strictEqual(stdout,`added workout workout11\n`);
+ });
+ });
+
+ it('should fail to create a workout when given the wrong number of attributes', async() => {
+ await assert.rejects(async() => await exec('./workouts --workout add workout12 0'));
+ await assert.rejects(async() => await exec('./workouts --workout add workout13 110'));
+ });
});
});
\ No newline at end of file
+++ /dev/null
-const assert = require('assert');
-const util = require('util');
-
-const exec = util.promisify(require('child_process').exec);
-const unlink = util.promisify(require('fs').unlink);
-
-describe('attr integration tests', () => {
-
- const attributes = [
- 'lower',
- 'upper',
- 'core',
- 'back',
- 'cardio',
- 'martial',
- 'other'
- ];
-
- describe('attr add', () => {
-
- it('should successfully add', async() => {
- for(const attr of attributes) {
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec(`./workouts attr add ${attr}`);
-
- assert.strictEqual(stdout,`New attribute added: ${attr}\n`);
- });
- }
- });
-
- it('should fail to add an attribute with the same name', async() => {
- await assert.rejects(async() => await exec('./workouts attr add other'));
- await assert.doesNotReject(async() => await exec('./workouts attr add Other'));
- });
-
- it('should fail when not given a name to add', async() => {
- await assert.rejects(async() => await exec('./workouts attr add'));
- });
-
- });
-
- describe('attr ls', () => {
-
- it('should successfully list all attributes in order they were added', async() => {
- attributes.push('Other');
-
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec(`./workouts attr`);
-
- let expected = "";
- for(const attr of attributes) {
- expected += `${attr}\n`;
- }
-
- assert.strictEqual(stdout,expected);
- });
-
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec(`./workouts attr ls`);
- let expected = "";
- for(const attr of attributes) {
- expected += `${attr}\n`;
- }
-
- assert.strictEqual(stdout,expected);
- });
- });
-
- });
-
- after(async() => {
- await unlink('workouts.db');
- });
-
-});
\ No newline at end of file
it('should print usage options when run with --help option', async() => {
let usage = `Usage:\n`;
- usage += `\tworkouts [options] [ls] [--filter {attribute filter}] [search term]\n`;
- usage += `\tworkouts [options] add [!name] [date]\n`;
- usage += `\tworkouts [options] new [!name] [attributes]\n`;
- usage += `\tworkouts [options] attr [ls]\n`;
- usage += `\tworkouts [options] attr add [!name]\n`;
+ usage += `\tworkouts [options] add [!name] [date] [attributes]\n`;
+ usage += `\tworkouts [options] ls [--filter {attribute filter}] [search term]\n`;
+ usage += `\tworkouts [options] rm [!name] [date]\n`;
usage += `\tworkouts [options] toggle [!workout name] [!attr]\n`;
- usage += `\tworkouts [options] recent\n`;
usage += `\n`;
usage += `Options:\n`;
+ usage += `\t--attribute, --attr, -a\n`;
usage += `\t--help, -h\n`;
usage += `\t--homedir, -d <path>\n`;
usage += `\t--quiet, -q\n`;
+ usage += `\t--recent, -l\n`;
usage += `\t--rows, -r <number>\n`;
usage += `\t--verbose, -v\n`;
+ usage += `\t--workout, -w\n`;
usage += `\n`;
usage += `{attribute filter} refers to a string of bit flags (0 = not, 1 = has, x = either) corresponding to active attributes.\n`;
usage += `Ex: 0100x00\n\n`
describe('ls integration tests', () => {
+ const recent = [
+ {name:"workout1",date:"2020-07-10"},
+ {name:"apple",date:"2020-07-09"},
+ {name:"test",date:"2020-07-09"},
+ {name:"workout2",date:"2020-07-09"}
+ ];
+
beforeEach(async() => {
- await assert.doesNotReject(async() => await exec('./workouts attr add lower'));
- await assert.doesNotReject(async() => await exec('./workouts attr add upper'));
+ await assert.doesNotReject(async() => await exec('./workouts --attr add lower'));
+ await assert.doesNotReject(async() => await exec('./workouts --attr add upper'));
+
+ await assert.doesNotReject(async() => await exec('./workouts --workout add workout1 01'));
+ await assert.doesNotReject(async() => await exec('./workouts --workout add workout2 10'));
+ await assert.doesNotReject(async() => await exec('./workouts --workout add test 00'));
+ await assert.doesNotReject(async() => await exec('./workouts --workout add apple 11'));
- await assert.doesNotReject(async() => await exec('./workouts new workout1 01'));
- await assert.doesNotReject(async() => await exec('./workouts new workout2 10'));
- await assert.doesNotReject(async() => await exec('./workouts new test 00'));
- await assert.doesNotReject(async() => await exec('./workouts new apple 11'));
+ for(const i of recent) {
+ await assert.doesNotReject(async() => await exec(`./workouts --recent add ${i.name} ${i.date}`));
+ }
});
afterEach(async() => {
await unlink('workouts.db');
});
- it('should succeed when no workouts are present', async() => {
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec('./workouts');
+ describe('ls_attribute', () => {
+ it('should successfully list all attributes in order they were added', async() => {
+ const attributes = ["lower","upper"];
- let expected = `Attributes:\tlower\tupper\t\n`;
- expected += `apple [3] [Last done: N/A]\n`;
- expected += `test [0] [Last done: N/A]\n`;
- expected += `workout1 [2] [Last done: N/A]\n`;
- expected += `workout2 [1] [Last done: N/A]\n`;
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec(`./workouts --attr ls`);
- assert.strictEqual(stdout,expected);
+ let expected = "";
+ for(const attr of attributes) {
+ expected += `${attr}\n`;
+ }
+
+ assert.strictEqual(stdout,expected);
+ });
});
});
- it('should successfully limit rows grabbed', async() => {
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec('./workouts --rows=1 ls');
+ describe('ls_recent', () => {
+
+ it('should successfully print recent workouts', async() => {
+ const {stdout,stderr} = await exec('./workouts --recent ls');
+
+ let expected = "";
+ for(const i of recent) {
+ expected += `${i.name}\t${i.date}\n`;
+ }
- let expected = `Attributes:\tlower\tupper\t\n`;
- expected += `apple [3] [Last done: N/A]\n`;
assert.strictEqual(stdout,expected);
});
+
});
- it('should successfully search for workouts', async() => {
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec('./workouts ls workout');
+ describe('ls_workouts', () => {
+
+ it('should succeed when no workouts are present', async() => {
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts');
- let expected = `Attributes:\tlower\tupper\t\n`;
- expected += `workout1 [2] [Last done: N/A]\n`;
- expected += `workout2 [1] [Last done: N/A]\n`;
+ let expected = `Attributes:\tlower\tupper\t\n`;
+ expected += `workout1 [2] [Last done: 2020-07-10]\n`;
+ expected += `apple [3] [Last done: 2020-07-09]\n`;
+ expected += `test [0] [Last done: 2020-07-09]\n`;
+ expected += `workout2 [1] [Last done: 2020-07-09]\n`;
- assert.strictEqual(stdout,expected);
+ assert.strictEqual(stdout,expected);
+ });
});
- });
- it('should reject when `ls` term is not given and attempting to filter', async() => {
- await assert.rejects(async() => {
- await exec('./workouts --filter 01');
+ it('should successfully limit rows grabbed', async() => {
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts --rows=1 ls');
+
+ let expected = `Attributes:\tlower\tupper\t\n`;
+ expected += `workout1 [2] [Last done: 2020-07-10]\n`;
+ assert.strictEqual(stdout,expected);
+ });
});
- });
- it('should successfully filter workouts by attribute', async() => {
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec('./workouts ls --filter 01');
+ it('should successfully search for workouts', async() => {
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts ls workout');
- let expected = `Attributes:\tlower\tupper\t\n`;
- expected += `workout2 [1] [Last done: N/A]\n`;
+ let expected = `Attributes:\tlower\tupper\t\n`;
+ expected += `workout1 [2] [Last done: 2020-07-10]\n`;
+ expected += `workout2 [1] [Last done: 2020-07-09]\n`;
- assert.strictEqual(stdout,expected);
+ assert.strictEqual(stdout,expected);
+ });
});
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec('./workouts ls --filter 10');
+ it('should reject when `ls` term is not given and attempting to filter', async() => {
+ await assert.rejects(async() => {
+ await exec('./workouts --filter 01');
+ });
+ });
+
+ it('should successfully filter workouts by attribute', async() => {
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts ls --filter 01');
- let expected = `Attributes:\tlower\tupper\t\n`;
- expected += `workout1 [2] [Last done: N/A]\n`;
+ let expected = `Attributes:\tlower\tupper\t\n`;
+ expected += `workout2 [1] [Last done: 2020-07-09]\n`;
- assert.strictEqual(stdout,expected);
- });
+ assert.strictEqual(stdout,expected);
+ });
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec('./workouts ls --filter x1');
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts ls --filter 10');
- let expected = `Attributes:\tlower\tupper\t\n`;
- expected += `apple [3] [Last done: N/A]\n`;
- expected += `workout2 [1] [Last done: N/A]\n`;
+ let expected = `Attributes:\tlower\tupper\t\n`;
+ expected += `workout1 [2] [Last done: 2020-07-10]\n`;
- assert.strictEqual(stdout,expected);
- });
+ assert.strictEqual(stdout,expected);
+ });
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec('./workouts ls --filter 00');
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts ls --filter x1');
- let expected = `Attributes:\tlower\tupper\t\n`;
- expected += `test [0] [Last done: N/A]\n`;
+ let expected = `Attributes:\tlower\tupper\t\n`;
+ expected += `apple [3] [Last done: 2020-07-09]\n`;
+ expected += `workout2 [1] [Last done: 2020-07-09]\n`;
- assert.strictEqual(stdout,expected);
+ assert.strictEqual(stdout,expected);
+ });
+
+ await assert.doesNotReject(async() => {
+ const {stdout,stderr} = await exec('./workouts ls --filter 00');
+
+ let expected = `Attributes:\tlower\tupper\t\n`;
+ expected += `test [0] [Last done: 2020-07-09]\n`;
+
+ assert.strictEqual(stdout,expected);
+ });
});
+
});
});
\ No newline at end of file
+++ /dev/null
-const assert = require('assert');
-const util = require('util');
-
-const exec = util.promisify(require('child_process').exec);
-const unlink = util.promisify(require('fs').unlink);
-
-describe('new integration tests', () => {
-
- beforeEach(async() => {
- await assert.doesNotReject(async() => await exec('./workouts attr add lower'));
- await assert.doesNotReject(async() => await exec('./workouts attr add upper'));
- });
-
- afterEach(async() => {
- await unlink('workouts.db');
- });
-
- it('should success creating a new workout', async() => {
- await assert.doesNotReject(async() => {
- const {stdout,stderr} = await exec('./workouts new workout1');
-
- assert.strictEqual(stdout,`New workout added: workout1\n`);
- });
- });
-
- it('should fail to create a workout when given the wrong number of attributes', async() => {
- await assert.rejects(async() => {
- const res = await exec('./workouts new workout1 0');
- console.log(res);
- });
- await assert.rejects(async() => await exec('./workouts new workout1 110'));
- });
-
-});
\ No newline at end of file
+++ /dev/null
-const assert = require('assert');
-const util = require('util');
-
-const exec = util.promisify(require('child_process').exec);
-const unlink = util.promisify(require('fs').unlink);
-
-describe('recent integration tests', () => {
-
- const recent = [
- {name:"workout1",date:"2020-07-10"},
- {name:"apple",date:"2020-07-09"},
- {name:"test",date:"2020-07-09"},
- {name:"workout2",date:"2020-07-09"}
- ];
-
- beforeEach(async() => {
- await assert.doesNotReject(async() => await exec('./workouts attr add lower'));
- await assert.doesNotReject(async() => await exec('./workouts attr add upper'));
-
- await assert.doesNotReject(async() => await exec('./workouts new workout1 01'));
- await assert.doesNotReject(async() => await exec('./workouts new workout2 10'));
- await assert.doesNotReject(async() => await exec('./workouts new test 00'));
- await assert.doesNotReject(async() => await exec('./workouts new apple 11'));
-
- for(const i of recent) {
- await assert.doesNotReject(async() => await exec(`./workouts add ${i.name} ${i.date}`));
- }
- });
-
- afterEach(async() => {
- await unlink('workouts.db');
- });
-
- it('should successfully print recent workouts', async() => {
- const {stdout,stderr} = await exec('./workouts recent');
-
- let expected = "";
- for(const i of recent) {
- expected += `${i.name}\t${i.date}\n`;
- }
-
- assert.strictEqual(stdout,expected);
- });
-
-});
\ No newline at end of file
describe('toggle integration tests', () => {
beforeEach(async() => {
- await assert.doesNotReject(async() => await exec('./workouts attr add lower'));
- await assert.doesNotReject(async() => await exec('./workouts attr add upper'));
+ await assert.doesNotReject(async() => await exec('./workouts --attr add lower'));
+ await assert.doesNotReject(async() => await exec('./workouts --attr add upper'));
- await assert.doesNotReject(async() => await exec('./workouts new workout1 01'));
- await assert.doesNotReject(async() => await exec('./workouts new workout2 10'));
- await assert.doesNotReject(async() => await exec('./workouts new test 00'));
- await assert.doesNotReject(async() => await exec('./workouts new apple 11'));
+ await assert.doesNotReject(async() => await exec('./workouts --workout add workout1 01'));
+ await assert.doesNotReject(async() => await exec('./workouts --workout add workout2 10'));
+ await assert.doesNotReject(async() => await exec('./workouts --workout add test 00'));
+ await assert.doesNotReject(async() => await exec('./workouts --workout add apple 11'));
});
afterEach(async() => {
EXTRA_DIST = \
test_utils.h \
add.tests.h \
- attr.tests.h \
data.attr.tests.h \
data.recent.tests.h \
data.workout.tests.h \
ls.tests.h \
- new.tests.h \
- recent.tests.h \
toggle.tests.h
-check_PROGRAMS = add.tests attr.tests data.attr.tests data.recent.tests data.workout.tests ls.tests new.tests recent.tests toggle.tests
+check_PROGRAMS = add.tests data.attr.tests data.recent.tests data.workout.tests ls.tests toggle.tests
TESTS = $(check_PROGRAMS)
if ENABLE_MEMCHECK
common_SOURCES += $(TEST_SRC_DIR)/default.c $(TEST_SRC_DIR)/log.c
common_SOURCES += $(TEST_SRC_DIR)/data/setup.c
-common_SOURCES += $(TEST_SRC_DIR)/opt/homedir.c $(TEST_SRC_DIR)/opt/loglvl.c $(TEST_SRC_DIR)/opt/rows.c
+common_SOURCES += $(TEST_SRC_DIR)/opt/homedir.c $(TEST_SRC_DIR)/opt/loglvl.c $(TEST_SRC_DIR)/opt/rows.c $(TEST_SRC_DIR)/opt/target.c
add_tests_SOURCES = \
$(common_SOURCES) \
$(TEST_SRC_DIR)/data/workout.c \
$(TEST_SRC_DIR)/usage.c
-attr_tests_SOURCES = \
- $(common_SOURCES) \
- attr.tests.c \
- $(TEST_SRC_DIR)/attr.c \
- $(TEST_SRC_DIR)/data/attr.c \
- $(TEST_SRC_DIR)/usage.c
-
data_attr_tests_SOURCES = \
$(common_SOURCES) \
data.attr.tests.c \
$(common_SOURCES) \
ls.tests.c \
$(TEST_SRC_DIR)/data/attr.c \
+ $(TEST_SRC_DIR)/data/recent.c \
$(TEST_SRC_DIR)/data/workout.c \
$(TEST_SRC_DIR)/ls.c \
$(TEST_SRC_DIR)/usage.c
-new_tests_SOURCES = \
- $(common_SOURCES) \
- new.tests.c \
- $(TEST_SRC_DIR)/data/attr.c \
- $(TEST_SRC_DIR)/data/workout.c \
- $(TEST_SRC_DIR)/new.c \
- $(TEST_SRC_DIR)/usage.c
-
-recent_tests_SOURCES = \
- $(common_SOURCES) \
- recent.tests.c \
- $(TEST_SRC_DIR)/data/recent.c \
- $(TEST_SRC_DIR)/recent.c
-
toggle_tests_SOURCES = \
$(common_SOURCES) \
toggle.tests.c \
int main() {
setup_env();
- add_basic_test();
+ add_attribute_basic_test();
+ add_recent_basic_test();
+ add_workout_basic_test();
clean();
return EXIT_SUCCESS;
}
-void add_basic_test() {
+void add_attribute_basic_test() {
+ global_opts.target = WORKOUT_DATA_TYPE_ATTRIBUTE;
+
+ char *argv[] = {
+ "add",
+ "alsdkfjalksdfj",
+ NULL
+ };
+
+ assert(EXIT_FAILURE==add(1,argv));
+ assert(EXIT_SUCCESS==add(2,argv));
+ assert(EXIT_FAILURE==add(2,argv));
+
+ reset_env();
+}
+
+void add_recent_basic_test() {
+ global_opts.target = WORKOUT_DATA_TYPE_RECENT;
+
char *bad_argv[] = {
"add",
"testworkout1notindb",
assert(EXIT_FAILURE==add(2,bad_argv));
assert(EXIT_FAILURE==add(3,bad_argv));
+ reset_env();
+}
+
+void add_workout_basic_test() {
+ global_opts.target = WORKOUT_DATA_TYPE_WORKOUT;
+
+ assert(attribute_insert("test")==1);
+ assert(attribute_insert("test2")==1);
+ assert(attribute_insert("test3")==1);
+ assert(attribute_insert("test4")==1);
+ assert(attribute_insert("test5")==1);
+ assert(attribute_insert("test6")==1);
+
+ char *argv[] = {
+ "add",
+ "testworkout",
+ "000012",
+ NULL
+ };
+
+ assert(EXIT_FAILURE==add(1,argv));
+ assert(EXIT_SUCCESS==add(2,argv));
+ assert(EXIT_FAILURE==add(3,argv));
+
+ argv[1] = "testworkout2";
+
+ assert(EXIT_SUCCESS==add(3,argv));
+
+ argv[1] = "testworkout3";
+ argv[2] = "000";
+
+ assert(EXIT_FAILURE==add(3,argv));
+
reset_env();
}
\ No newline at end of file
#include<add.h>
int main();
-void add_basic_test();
+void add_attribute_basic_test();
+void add_recent_basic_test();
+void add_workout_basic_test();
#endif
\ No newline at end of file
+++ /dev/null
-#include<attr.tests.h>
-
-int main() {
- setup_env();
-
- attr_basic_test();
-
- clean();
-
- return EXIT_SUCCESS;
-}
-
-void attr_basic_test() {
- char *argv[] = {
- "attr",
- "add",
- "alsdkfjalksdfj",
- NULL
- };
-
- char *ls_argv[] = {
- "attr",
- "ls",
- NULL
- };
-
- char *bad_argv[] = {
- "attr",
- "hahaha",
- "asdfoiasdf",
- NULL
- };
-
- assert(EXIT_SUCCESS==attr(1,ls_argv));
- assert(EXIT_SUCCESS==attr(2,ls_argv));
-
- assert(EXIT_SUCCESS==attr(1,bad_argv));
- assert(EXIT_FAILURE==attr(2,bad_argv));
- assert(EXIT_FAILURE==attr(3,bad_argv));
-
- assert(EXIT_SUCCESS==attr(1,argv));
- assert(EXIT_FAILURE==attr(2,argv));
- assert(EXIT_SUCCESS==attr(3,argv));
-
- reset_env();
-}
\ No newline at end of file
+++ /dev/null
-#ifndef __ATTR_TESTS_H_
-#define __ATTR_TESTS_H_
-
-#include<test_utils.h>
-
-#include<attr.h>
-
-int main();
-void attr_basic_test();
-
-#endif
\ No newline at end of file
setup_env();
attribute_count_test();
+ attribute_delete_test();
attribute_get_test();
attribute_index_test();
attribute_insert_test();
int i;
+void attribute_delete_test() {
+ i = 0;
+ assert(attribute_get(&attribute_get_test_helper)==1);
+ assert(i==0);
+
+ assert(attribute_insert("test")==1);
+ assert(attribute_get(&attribute_get_test_helper)==1);
+ assert(i==1);
+
+ assert(attribute_delete("test")==1);
+
+ i = 0;
+ assert(attribute_get(&attribute_get_test_helper)==1);
+ assert(i==0);
+
+ reset_env();
+}
+
void attribute_get_test() {
i = 0;
assert(attribute_get(&attribute_get_test_helper)==1);
int main();
void attribute_count_test();
+void attribute_delete_test();
void attribute_get_test();
void attribute_get_test_helper(const unsigned char*);
void attribute_index_test();
int main() {
setup_env();
+ recent_delete_test();
recent_get_test();
recent_insert_test();
int i;
+void recent_delete_test() {
+ assert(workout_insert("test",0)==1);
+ assert(recent_insert("test","2020-10-12")==1);
+
+ i = 0;
+ assert(recent_get(-1,&recent_get_test_helper)==1);
+ assert(i==1);
+
+ assert(recent_delete("test","2020-10-12")==1);
+
+ i = 0;
+ assert(recent_get(-1,&recent_get_test_helper)==1);
+ assert(i==0);
+
+ reset_env();
+}
+
+
void recent_get_test() {
i = 0;
assert(recent_get(-1,&recent_get_test_helper)==1);
#include<test_utils.h>
int main();
+void recent_delete_test();
void recent_get_test();
void recent_get_test_helper(const unsigned char*,const unsigned char*);
void recent_insert_test();
int main() {
setup_env();
+ workout_delete_test();
workout_get_test();
workout_insert_test();
workout_toggle_test();
int i;
+void workout_delete_test() {
+ i = 0;
+ assert(workout_get(NULL,NULL,-1,&workout_get_test_helper)==1);
+ assert(i==0);
+
+ assert(workout_insert("test",0)==1);
+
+ i = 0;
+ assert(workout_get(NULL,NULL,-1,&workout_get_test_helper)==1);
+ assert(i==1);
+
+ assert(workout_delete("test")==1);
+
+ i = 0;
+ assert(workout_get(NULL,NULL,-1,&workout_get_test_helper)==1);
+ assert(i==0);
+
+ reset_env();
+}
+
void workout_get_test() {
i = 0;
#include<test_utils.h>
int main();
+void workout_delete_test();
void workout_get_test();
void workout_get_test_helper();
void workout_insert_test();
int main() {
setup_env();
- ls_basic_test();
+ ls_attribute_basic_test();
+ ls_recent_basic_test();
+ ls_workout_basic_test();
clean();
return EXIT_SUCCESS;
}
-void ls_basic_test() {
+void ls_attribute_basic_test() {
+ assert(EXIT_SUCCESS==ls_attribute());
+}
+
+void ls_recent_basic_test() {
+ assert(EXIT_SUCCESS==ls_recent());
+}
+
+void ls_workout_basic_test() {
+ global_opts.target = WORKOUT_DATA_TYPE_WORKOUT;
+
char *bad_opt[] = {
"ls",
"-b",
#include<ls.h>
int main();
-void ls_basic_test();
+void ls_attribute_basic_test();
+void ls_recent_basic_test();
+void ls_workout_basic_test();
#endif
\ No newline at end of file
+++ /dev/null
-#include<new.tests.h>
-
-int main() {
- setup_env();
-
- new_basic_test();
-
- clean();
-
- return EXIT_SUCCESS;
-}
-
-void new_basic_test() {
- char *bad[] = {
- "new",
- "testworkout",
- "012001",
- NULL
- };
-
- assert(attribute_insert("test")==1);
- assert(attribute_insert("test2")==1);
- assert(attribute_insert("test3")==1);
- assert(attribute_insert("test4")==1);
- assert(attribute_insert("test5")==1);
- assert(attribute_insert("test6")==1);
-
- assert(EXIT_FAILURE==new_workout(1,bad));
- assert(EXIT_SUCCESS==new_workout(2,bad));
- assert(EXIT_FAILURE==new_workout(3,bad));
-
- char *argv[] = {
- "new",
- "test workout",
- "010001",
- NULL
- };
-
- assert(EXIT_SUCCESS==new_workout(3,argv));
-
- reset_env();
-}
\ No newline at end of file
+++ /dev/null
-#ifndef __NEW_TESTS_H_
-#define __NEW_TESTS_H_
-
-#include<test_utils.h>
-
-#include<new.h>
-
-int main();
-void new_basic_test();
-
-#endif
\ No newline at end of file
+++ /dev/null
-#include<recent.tests.h>
-
-int main() {
- setup_env();
-
- recent_basic_test();
-
- clean();
-
- return EXIT_SUCCESS;
-}
-
-void recent_basic_test() {
- assert(EXIT_SUCCESS==recent());
-}
\ No newline at end of file
+++ /dev/null
-#ifndef __RECENT_TESTS_H_
-#define __RECENT_TESTS_H_
-
-#include<test_utils.h>
-
-#include<recent.h>
-
-int main();
-void recent_basic_test();
-
-#endif
\ No newline at end of file