/* * recenteditor_data.c * * A programmers editor * * Tests (ensure correct functionality of modules) * * Author: Dario Rodriguez dario@softhome.net * This program is licensed under the terms of GNU GPL v2.1+ */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <limits.h> #include <fcntl.h> #include <errno.h> #include "recenteditor_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[]) { 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", "A,0,$,Testing add$",0,0}, }; redata_t *redata; int i; int nerrors; char *res; for(i=0,nerrors=0;i<(sizeof(tests)/sizeof(tests[0]));i++) { if((redata=redata_init())==NULL) { fprintf(stderr,"ERROR: problem initializing redata module\n"); return(1); } 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++; } redata_free(redata),redata=NULL; } fprintf(stderr,"\n"); if(nerrors==0) fprintf(stderr,"All tests passed OK\n"); else fprintf(stderr,"%i test(s) failed of %i tests run.\n",nerrors,i); 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<size;i++) ((unsigned char *)mem)[i]=(i%256); } else { srandom(*((unsigned int *)(&seed))); for(i=0;i<size;i++) ((unsigned char *)mem)[i]=(random()&0xff); } return(mem); } static int write_file(char *filename, char *buf, int buflen) { int fd; if((fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0644))==-1) { free(buf),buf=NULL; return(-1); } write(fd,buf,buflen); close(fd),fd=-1; return(0); } char * test_newfile(redata_t *redata, char *filename, char *dummy, int filesize, int dummy2) { char *mem; char hash129_pre[129]; char hash129_post[129]; fprintf(stderr,"\ntest_newfile(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL)?"\"":"",(filename!=NULL)?filename:"NULL",(filename!=NULL)?"\"":"",(dummy!=NULL)?"\"":"",(dummy!=NULL)?dummy:"NULL",(dummy!=NULL)?"\"":"",filesize,dummy2); /* prepare file for loading */ if((mem=malloc_data(filesize,0))==NULL) return("insuf. mem. for temp. buffer"); if(write_file(filename,mem,filesize)==-1) return("couldn't create temporary file"); redata_filehash(redata,filename,hash129_pre); free(mem),mem=NULL; /* load file */ if(redata_load(redata,filename,0)!=0) { unlink(filename); return("couldn't load file"); } unlink(filename); redata_hash(redata,hash129_post); if(strcmp(hash129_pre,hash129_post)!=0) return("loaded file is corrupted"); /* save file */ redata_save(redata,filename); hash129_post[0]='\0'; redata_filehash(redata,filename,hash129_post); if(strcmp(hash129_pre,hash129_post)!=0) return("saved file is corrupted"); unlink(filename); return(TEST_OK); } char * test_edit(redata_t *redata, char *filename, char *edits, int filesize, int seed) { static char errorbuf[256]; char progress[256]; int k; int cursize; char *ptr; int l; char *mem; char endcode; char *ptrend; int size; char hash129_memold[129]; char hash129_mem[129]; char hash129_redata[129]; mem=NULL; fprintf(stderr,"\ntest_edit(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL)?"\"":"",(filename!=NULL)?filename:"NULL",(filename!=NULL)?"\"":"",(edits!=NULL)?"\"":"",(edits!=NULL)?edits:"NULL",(edits!=NULL)?"\"":"",filesize,seed); /* two passes: k==0 count needed memory, k==1 do edits */ for(k=0,cursize=filesize,progress[0]='\0';k<2;k++,cursize=0,progress[0]='\0') { for(ptr=edits;*ptr!='\0';) { if(k!=0) { redata_memhash(redata,mem,cursize,hash129_memold); } if((l=strlen(progress))<(sizeof(progress)-1)) { progress[l]=(l<(sizeof(progress)-2))?*ptr:'+'; progress[l+1]='\0'; } if(*ptr=='A') { /* A,<insertpos>,<endchar>,<text><endchar> */ ptr++; ptr+=(*ptr==',')?1:0; 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"); } ptr+=(*ptr==',')?1:0; 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(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(k!=0) { 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); 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); 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(cursize,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,0)!=0) { unlink(filename); return("couldn't load file"); } unlink(filename); } } if(mem!=NULL) free(mem),mem=NULL; return(TEST_OK); }