/* * re_tests.c * * A programmers editor * * Tests (ensure correct functionality of modules) * * Author: Dario Rodriguez antartica@whereismybit.com * This program is licensed under the terms of GNU GPL v2.1+ */ #include #include #include #include #include #include #include #include "re_data.h" #define PREFIX "retest_" #define TEST_OK "OK" typedef struct test_t { char *name; char *(*fn)(redata_t *,char *,char *, int, int); char *param1; char *param2; int int1; int int2; } test_t; static char *malloc_data(int size, int seed); static int write_file(char *filename, char *buf, int buflen); char *test_newfile(redata_t *redata, char *filename, char *dummy, int filesize, int dummy2); char *test_edit(redata_t *redata, char *filename, char *edits, int filesize, int seed); int main(int argc, char *argv[]) { static int sizes[]={-1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,30,31,32,33,63,64,65,127,128,129,1023,1024,1025,16384}; test_t tests[]={ {"newfile_16",test_newfile,PREFIX "FILE", NULL, 16, 0}, {"newfile_1024",test_newfile,PREFIX "FILE", NULL, 1024, 0}, {"newfile_32767",test_newfile,PREFIX "FILE", NULL, 32767, 0}, {"newfile_32768",test_newfile,PREFIX "FILE", NULL, 32768, 0}, {"newfile_32769",test_newfile,PREFIX "FILE", NULL, 32769, 0}, {"newfile_131072",test_newfile,PREFIX "FILE", NULL, 131072, 0}, {"testedit_add",test_edit,PREFIX "EDIT", "A0$Testing add$",0,0}, {"testedit_del",test_edit,PREFIX "EDIT", "A0$Testing add/del$D8$add/$",0,0}, {"testedit_move",test_edit,PREFIX "EDIT", "A0$This is a text to move.$M17,7$ move$",0,0}, }; int flag_exit=0,flag_all=0; redata_t *redata; int i,s; int nerrors,total; char *res; for(i=1;i=1024) continue; /* too slow: skip unless testing --all */ if((redata=redata_init(NULL))==NULL) { fprintf(stderr,"ERROR: problem initializing redata module\n"); return(1); } if(sizes[s]!=-1) redata_config_chunkdatasize(redata,sizes[s]); fprintf(stderr,"%s...",tests[i].name); res=tests[i].fn(redata,tests[i].param1,tests[i].param2,tests[i].int1,tests[i].int2); if(strcmp(res,TEST_OK)==0) { fprintf(stderr," ok.\n"); } else { fprintf(stderr," ERROR: %s\n",res); nerrors++; if(flag_exit) { /* exit on first error */ s=sizeof(sizes)/sizeof(sizes[0]); break; } } redata_free(redata),redata=NULL; } fprintf(stderr,"\n"); } if(nerrors==0) fprintf(stderr,"All %i tests passed OK\n",total); else fprintf(stderr,"%i test(s) failed of %i tests run.\n",nerrors,total); redata_free(redata),redata=NULL; return((nerrors==0)?0:1); } static char * malloc_data(int size, int seed) { char *mem; int i; if(size<=0 || (mem=malloc(size))==NULL) return(NULL); memset(mem,0,size); if(seed==0) { for(i=0;i */ ptr++; errno=0; l=(int)strtol(ptr,&ptr,10); if(errno!=0 || l<0 || l>cursize) { if(mem!=NULL) free(mem),mem=NULL; return("test_edit(): error parsing position"); } endcode=*ptr; ptr+=(*ptr!='\0')?1:0; ptrend=strchr(ptr,endcode); ptrend=(ptrend==NULL)?ptr+strlen(ptr):ptrend; size=ptrend-ptr; if(k!=0) { /* editing */ memmove(mem+l+size,mem+l,cursize-l); memcpy(mem+l,ptr,size); redata_op_add(redata,l,ptr,size,NULL); } cursize+=size; ptr+=size; ptr+=(*ptr!='\0')?1:0; } else if(*ptr=='D') { /* D */ ptr++; errno=0; l=(int)strtol(ptr,&ptr,10); if(errno!=0) { if(mem!=NULL) free(mem),mem=NULL; return("test_edit(): error parsing position"); } endcode=*ptr; ptr+=(*ptr!='\0')?1:0; ptrend=strchr(ptr,endcode); ptrend=(ptrend==NULL)?ptr+strlen(ptr):ptrend; size=ptrend-ptr; if(l<0 || (l+size)>cursize) { if(mem!=NULL) free(mem),mem=NULL; return("test_edit(): internal error: invalid pasition or size"); } if(k!=0) { if(memcmp(mem+l,ptr,size)!=0 || redata_data_compare(redata,l,ptr,size)!=0) { if(mem!=NULL) free(mem),mem=NULL; return("test_edit(): internal error: deletion data doesn't match"); } /* editing */ memmove(mem+l,mem+l+size,cursize-l-size); redata_op_del(redata,l,size,NULL); } cursize-=size; ptr+=size; ptr+=(*ptr!='\0')?1:0; } else if(*ptr=='M') { /* M, */ ptr++; errno=0; l=(int)strtol(ptr,&ptr,10); if(errno!=0) { if(mem!=NULL) free(mem),mem=NULL; return("test_edit(): error parsing position"); } ptr+=(*ptr==',')?1:0; errno=0; o=(int)strtol(ptr,&ptr,10); if(errno!=0) { if(mem!=NULL) free(mem),mem=NULL; return("test_edit(): error parsing position"); } endcode=*ptr; ptr+=(*ptr!='\0')?1:0; ptrend=strchr(ptr,endcode); ptrend=(ptrend==NULL)?ptr+strlen(ptr):ptrend; size=ptrend-ptr; if(l<0 || (l+size)>cursize || o<0 || o>cursize || (o>=l && o<(l+size))) { if(mem!=NULL) free(mem),mem=NULL; return("test_edit(): internal error: invalid pasition or size"); } if(k!=0) { if(memcmp(mem+l,ptr,size)!=0 || redata_data_compare(redata,l,ptr,size)!=0) { if(mem!=NULL) free(mem),mem=NULL; return("test_edit(): internal error: move data doesn't match"); } /* editing */ if(l>o) { memmove(mem+o+size,mem+o,l-o); memcpy(mem+o,ptr,size); } else { memmove(mem+l,mem+l+size,o-l-size); memcpy(mem+o-size,ptr,size); } redata_op_move(redata,l,size,o,NULL); } ptr+=size; ptr+=(*ptr!='\0')?1:0; } else { if(mem!=NULL) free(mem),mem=NULL; snprintf(errorbuf,sizeof(errorbuf), "test_edit(): unknown edit action at pos %i: '%c' (progress: %s)",(int) (ptr-edits),*ptr,progress); errorbuf[sizeof(errorbuf)-1]='\0'; return(errorbuf); } if(cursize>maxsize) maxsize=cursize; if(k!=0) { if(k!=0) redata_save(redata,"test.post",NULL); redata_hash(redata,hash129_redata); redata_memhash(redata,mem,cursize,hash129_mem); if(strcmp(hash129_redata,hash129_mem)!=0) { if(mem!=NULL) free(mem),mem=NULL; snprintf(errorbuf,sizeof(errorbuf), "corrupted edit before pos %i (progress: %s)",(int) (ptr-edits),progress); errorbuf[sizeof(errorbuf)-1]='\0'; return(errorbuf); } redata_op_undo(redata,NULL); redata_save(redata,"test.undo",NULL); redata_hash(redata,hash129_redata); if(strcmp(hash129_redata,hash129_memold)!=0) { if(mem!=NULL) free(mem),mem=NULL; snprintf(errorbuf,sizeof(errorbuf), "corrupted undo before pos %i (progress: %s)",(int) (ptr-edits),progress); errorbuf[sizeof(errorbuf)-1]='\0'; return(errorbuf); } redata_op_redo(redata,NULL); redata_save(redata,"test.redo",NULL); redata_hash(redata,hash129_redata); if(strcmp(hash129_redata,hash129_mem)!=0) { if(mem!=NULL) free(mem),mem=NULL; snprintf(errorbuf,sizeof(errorbuf), "corrupted redo before pos %i (progress: %s)",(int) (ptr-edits),progress); errorbuf[sizeof(errorbuf)-1]='\0'; return(errorbuf); } } } if(k==0) { /* reserve memory, do init */ if((mem=malloc_data(maxsize,seed))==NULL) return("insuf. mem. for temp. buffer"); if(write_file(filename,mem,filesize)==-1) return("couldn't create temporary file"); if(redata_load(redata,filename,NULL)!=0) { unlink(filename); return("couldn't load file"); } unlink(filename); } } if(mem!=NULL) free(mem),mem=NULL; unlink("test.pre"),unlink("test.post"),unlink("test.undo"),unlink("test.redo"); return(TEST_OK); }