/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*
Copyright (c) 2013 D. Richard Hipp
This program is free software; you can redistribute it and/or
modify it under the terms of the Simplified BSD License (also
known as the "2-Clause License" or "FreeBSD License".)
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose.
Author contact information:
drh@hwaci.com
http://www.hwaci.com/drh/
*****************************************************************************
Test/demo code for the fossil library API.
*/
/* Force assert() to always work... */
#if defined(NDEBUG)
#undef NDEBUG
#define DEBUG 1
#endif
#define THIS_SRC_FNAME "test.c"
#include "libfossil.h"
#include <assert.h>
#include <stdio.h>
#define MARKER(pfexp) \
do{ printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); \
printf pfexp; \
} while(0)
static int test0(){
fsl_cx * f = fcli_cx();
int rc = 0;
if(fsl_cx_db_repo(f)){
f_out("ID of tag 'sym-trunk'=%"FSL_ID_T_PFMT"\n",
fsl_tag_id(f, "sym-trunk", 0));
f_out("ID of tag 'tag-creation-test2'=%"FSL_ID_T_PFMT"\n",
fsl_tag_id(f, "tag-creation-test2", 1));
assert(0 == fsl_tag_id(f, "no-such-tag", 0));
}
if(fsl_cx_db_ckout(f)){
fsl_id_t id = 0, id2 = 0;
char * uuid = 0;
f_out("Running sym-to-rid tests...\n");
id = 0;
rc = fsl_sym_to_rid(f, "tip", FSL_SATYPE_ANY, &id);
assert(0==rc);
assert(id>0);
id = 0;
rc = fsl_sym_to_rid(f, "current", FSL_SATYPE_ANY, &id);
f_out("rc=%d/%s\n", rc, fsl_rc_cstr(rc));
assert(0==rc);
assert(id>0);
assert(!fsl_content_is_private(f,id));
id = 0;
rc = fsl_sym_to_rid(f, "9d8c610ad6", FSL_SATYPE_CHECKIN, &id);
assert(0==rc);
assert(id>0);
id = 0;
rc = fsl_sym_to_rid(f, "9d8c610ad6", FSL_SATYPE_WIKI, &id);
assert(FSL_RC_NOT_FOUND==rc);
assert(id==0);
fsl_cx_err_reset(f) /* stop propagation of that error. */;
id = 0;
rc = fsl_sym_to_rid(f, "trunk", FSL_SATYPE_ANY, &id);
assert(0==rc);
assert(id>0);
assert(fsl_rid_is_leaf(f, id));
assert(0 == fsl_count_nonbranch_children(f, id));
if(0){
fsl_buffer buf = fsl_buffer_empty;
rc = fsl_content_blob(f, id, &buf);
assert(!rc);
f_out("Control artifact for rid #%"FSL_ID_T_PFMT":\n%s",
id, fsl_buffer_cstr(&buf));
fsl_buffer_clear(&buf);
}
id = 0;
rc = fsl_sym_to_rid(f, "prev", FSL_SATYPE_CHECKIN, &id);
assert(0==rc);
assert(id>0);
assert(!fsl_rid_is_leaf(f, id));
assert(0 < fsl_count_nonbranch_children(f, id));
id = 0;
rc = fsl_sym_to_rid(f, "current", FSL_SATYPE_CHECKIN, &id);
assert(0==rc);
assert(id>0);
rc = fsl_sym_to_uuid(f, "current", FSL_SATYPE_CHECKIN, &uuid, &id2);
assert(0==rc);
assert(uuid);
assert(id2 == id);
assert(fsl_is_uuid(uuid));
f_out("Current checkout: %s\n", uuid);
fsl_free(uuid);
}
return rc;
}
/* static */ int test_leaves_rebuild(){
int rc;
f_out("Rebuilding leaves...\n");
rc = fsl_repo_leaves_rebuild(fcli_cx());
assert(!rc);
f_out("Done rebuilding leaves.\n");
return rc;
}
static int test_content_get(){
char const * sym =
/* some version of th1ish/test-003.th1ish */
"33b40942db0c00eba3a2a0bf1e61ea5c573e902f" /* first version */
;
int rc;
fsl_id_t rid = 0;
fsl_buffer c = fsl_buffer_empty;
fsl_cx * f = fcli_cx();
rc = fsl_sym_to_rid(f, sym, FSL_SATYPE_ANY, &rid);
assert(!rc);
assert(rid>0);
rc = fsl_content_get(f, rid, &c);
fsl_cx_err_report(f, 1);
assert(!rc);
assert(1032==c.used);
rc = fsl_sha1sum_buffer( &c, &c );
assert(!rc);
assert(fsl_is_uuid_len((int)c.used));
assert(0==fsl_strcmp( sym, fsl_buffer_cstr(&c) ));
/* Now fetch a few other versions of that same file
and ensure that they meet our expectations...
*/
sym = "e9b776a8a72753823e4553a309edae21897cb2c4";
rid = 0;
rc = fsl_sym_to_rid(f, sym, FSL_SATYPE_ANY, &rid);
assert(!rc);
assert(rid>0);
rc = fsl_content_get(f, rid, &c);
assert(!rc);
assert(2076==c.used);
rc = fsl_sha1sum_buffer( &c, &c );
assert(!rc);
assert(fsl_is_uuid_len((int)c.used));
assert(0==fsl_strcmp( sym, fsl_buffer_cstr(&c) ));
sym = "f7d3a2e155d59a96ecc37001b05de26dee23c0cf";
rid = 0;
rc = fsl_sym_to_rid(f, sym, FSL_SATYPE_ANY, &rid);
assert(!rc);
assert(rid>0);
rc = fsl_content_get(f, rid, &c);
assert(!rc);
assert(2481==c.used);
rc = fsl_sha1sum_buffer( &c, &c );
assert(!rc);
assert(fsl_is_uuid_len((int)c.used));
assert(0==fsl_strcmp( sym, fsl_buffer_cstr(&c) ));
sym = "31e01e2a3c";
rid = 0;
rc = fsl_sym_to_rid(f, sym, FSL_SATYPE_WIKI, &rid);
assert(!rc);
assert(rid>0);
rc = fsl_content_get(f, rid, &c);
#if 1
if(0){
f_out("got content [%s]:\n%.*s", sym, (int)c.used,
(char const *)c.mem);
}else{
f_out("got content [%.*s]: %d byte(s)\n", 8, sym, (int)c.used);
}
#endif
fsl_buffer_clear(&c);
return rc;
}
static int test_hash_this_file(){
fsl_buffer hash = fsl_buffer_empty;
int rc;
rc = fsl_md5sum_filename(THIS_SRC_FNAME, &hash);
assert(!rc);
f_out("MD5 of this file: %s\n", fsl_buffer_cstr(&hash));
rc = fsl_sha1sum_filename(THIS_SRC_FNAME, &hash);
assert(!rc);
f_out("SHA1 of this file: %s\n", fsl_buffer_cstr(&hash));
fsl_buffer_clear(&hash);
return rc;
}
static int test_text_diff(){
fsl_buffer lhs = fsl_buffer_empty;
fsl_buffer rhs = fsl_buffer_empty;
fsl_buffer diff = fsl_buffer_empty;
int rc;
int context = 1;
rc = fsl_buffer_fill_from_filename(&lhs, THIS_SRC_FNAME);
assert(!rc);
rc = fsl_buffer_append( &rhs, lhs.mem, lhs.used );
assert(!rc);
for( rc = 0; rc < 20; ++rc ){
rhs.mem[rc + 100] = '*';
}
rc = fsl_diff_text_to_buffer( &lhs, &rhs, &diff, context, 0,
FSL_DIFF_ANSI_COLOR);
f_out("diff rc=%s, output len=%"FSL_SIZE_T_PFMT"\n", fsl_rc_cstr(rc), diff.used);
f_out("Diff from this file and a mangled copy:\n%b", &diff);
fsl_buffer_clear(&diff);
f_out("\nInverted...\n");
rc = fsl_diff_text( &lhs, &rhs, fsl_output_f_FILE, stdout, context, 0,
FSL_DIFF_INVERT | FSL_DIFF_ANSI_COLOR);
f_out("\nWith line numbers...\n");
rc = fsl_diff_text( &lhs, &rhs, fsl_output_f_FILE, stdout, context, 0,
FSL_DIFF_LINENO | FSL_DIFF_ANSI_COLOR);
f_out("\nSide-by-side...\n");
rc = fsl_diff_text( &lhs, &rhs, fsl_output_f_FILE, stdout,
context, 30,
0 /*FSL_DIFF_SIDEBYSIDE is implicit when sbsWidth>0*/
| FSL_DIFF_ANSI_COLOR);
f_out("\nInverted...\n");
rc = fsl_diff_text( &lhs, &rhs, fsl_output_f_FILE, stdout,
context, 30,
FSL_DIFF_INVERT | FSL_DIFF_ANSI_COLOR);
if(0){
f_out("\nAnd using HTML...\n");
rc = fsl_diff_text( &lhs, &rhs, fsl_output_f_FILE, stdout, 3, 80,
FSL_DIFF_SIDEBYSIDE | FSL_DIFF_HTML);
}
fsl_buffer_clear(&lhs);
fsl_buffer_clear(&rhs);
#if 0
printf("[%*s]\n", 7, "-----");
f_out("[%*s]\n", 7, "-----");
printf("[%7s]\n", "-----");
f_out("[%7s]\n", "-----");
printf("[%*s]\n", 3, "-----");
f_out("[%*s]\n", 3, "-----");
printf("[%3s]\n", "-----");
f_out("[%3s]\n", "-----");
printf("[%.*s]\n", 7, "-----");
f_out("[%.*s]\n", 7, "-----");
printf("[%.*s]\n", 3, "-----");
f_out("[%.*s]\n", 3, "-----");
printf("[%*s]\n", 10, "-----");
f_out("[%*s]\n", 10, "-----");
printf("[%-*s]\n", 10, "-----");
f_out("[%-*s]\n", 10, "-----");
#endif
return rc;
}
#include <zlib.h>
#include <memory.h> /* memset() and friends */
static void test_zip(){
fsl_zip_writer z = fsl_zip_writer_empty;
int rc;
char const * zFile;
fsl_time_t tm = 61;
fsl_buffer content = fsl_buffer_empty;
fsl_buffer const * zipBody;
MARKER(("zip testing...\n"));
rc = fsl_buffer_fill_from_filename(&content, THIS_SRC_FNAME);
assert(0==rc);
assert(content.used);
zFile = "a/b/foo.txt";
fsl_zip_timestamp_set_unix(&z, tm);
rc = fsl_zip_file_add(&z, zFile, &content, FSL_FILE_PERM_REGULAR );
assert(0==rc);
assert(3==z.entryCount);
assert(2==z.dirs.used);
zFile = "a/b/c/bar.txt";
fsl_zip_timestamp_set_unix(&z, tm+=60);
rc = fsl_zip_file_add(&z, zFile, &content, FSL_FILE_PERM_REGULAR );
assert(0==rc);
assert(5==z.entryCount);
assert(3==z.dirs.used);
zFile = "a/b/c/baz.txt";
fsl_zip_timestamp_set_unix(&z, tm+=60);
rc = fsl_zip_file_add(&z, zFile, &content, FSL_FILE_PERM_REGULAR );
assert(0==rc);
assert(6==z.entryCount);
assert(3==z.dirs.used);
fsl_buffer_clear(&content);
assert(z.body.used);
assert(z.toc.used);
fsl_zip_end(&z);
assert(z.body.used);
assert(z.body.mem);
assert(!z.toc.used);
assert(!z.toc.mem);
zipBody = fsl_zip_body(&z);
zFile = "zipped.zip";
fsl_file_unlink(zFile) /* ignore error - this is just precautionary */;
rc = fsl_buffer_to_filename(zipBody, zFile);
assert(!rc);
MARKER(("Check the zip file: %s\n", zFile));
fsl_zip_finalize(&z);
}
int main(int argc, char const * const * argv ){
int rc = 0;
fcli_cliflag cliFlags[] = {
fcli_cliflag_empty_m
};
fcli_help_info FCliHelp = {
"This is a scratchpad app.",
NULL, NULL
};
fcli.cliFlags = cliFlags;
fcli.appHelp = &FCliHelp;
rc = fcli_setup(argc, argv);
if(rc) goto end;
rc = test0();
#if 0 && defined(SQLITE_FCNTL_TEMPFILENAME)
if(!rc) rc = test_tmpfile_0();
#endif
if(!rc && fsl_cx_db_repo(fcli_cx())){
/* rc = test_leaves_rebuild(); */
if(!rc) rc = test_content_get();
}
if(!rc){
rc = test_hash_this_file();
}
if(!rc){
rc = test_text_diff();
}
test_zip();
end:
f_out("Done! rc=%d (%s)\n", rc, fsl_rc_cstr(rc));
return fcli_end_of_main(rc);
}
#undef MARKER