Login
test.c at [c5b01a0b83]
Login

File f-apps/test.c artifact 8e2b7fcc5e part of check-in c5b01a0b83


/* -*- 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

#ifdef _MSC_VER
#define THIS_SRC_FNAME "test.c"
/*A peculiarity of msvc x64 compiler (and not x86!) is that __FILE__ will be
a relative path as seen at compile-time.  But since the cwd of the compiler is
not the source dir, this relative path will be incorrect at runtime, when our
cwd IS in the source dir, and tests will fail.*/
#else
#define THIS_SRC_FNAME __FILE__
#endif

#include "fossil-scm/fossil-internal.h"
#include "fossil-scm/fossil-cli.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.f;
 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_checkout(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_CATYPE_ANY, &id);
    assert(0==rc);
    assert(id>0);

    id = 0;
    rc = fsl_sym_to_rid(f, "current", FSL_CATYPE_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_CATYPE_CHECKIN, &id);
    assert(0==rc);
    assert(id>0);

    id = 0;
    rc = fsl_sym_to_rid(f, "9d8c610ad6", FSL_CATYPE_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_CATYPE_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_CATYPE_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_CATYPE_CHECKIN, &id);
    assert(0==rc);
    assert(id>0);

    rc = fsl_sym_to_uuid(f, "current", FSL_CATYPE_CHECKIN, &uuid, &id2);
    assert(0==rc);
    assert(uuid);
    assert(id2 == id);
    assert(FSL_UUID_STRLEN==fsl_strlen(uuid));
    f_out("Current checkout: %.*s\n", FSL_UUID_STRLEN, uuid);
    fsl_free(uuid);
    
  }
  return rc;
}

/* static */ int test_leaves_rebuild(){
  int rc;
  f_out("Rebuilding leaves...\n");
  rc = fsl_repo_leaves_rebuild(fcli.f);
  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.f;
  rc = fsl_sym_to_rid(f, sym, FSL_CATYPE_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_UUID_STRLEN==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_CATYPE_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_UUID_STRLEN==c.used);
  assert(0==fsl_strcmp( sym, fsl_buffer_cstr(&c) ));

  sym = "f7d3a2e155d59a96ecc37001b05de26dee23c0cf";
  rid = 0;
  rc = fsl_sym_to_rid(f, sym, FSL_CATYPE_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_UUID_STRLEN==c.used);
  assert(0==fsl_strcmp( sym, fsl_buffer_cstr(&c) ));


  sym = "31e01e2a3c";
  rid = 0;
  rc = fsl_sym_to_rid(f, sym, FSL_CATYPE_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);
}

static void fcli_local_help(){
  puts("This is a scratchpad app and has no help.");
}

int main(int argc, char * const * argv ){
  int rc = 0;
  assert(sizeof(fsl_int32_t) >= 4);
  assert(sizeof(fsl_int64_t) >= 8);
  fcli.appHelp = fcli_local_help;
  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.f)){
    /* 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_err_report(0) || rc)
    ? EXIT_FAILURE : EXIT_SUCCESS;
}

#undef MARKER