/*
 * NAME
 *   VarBufTest.c
 * DESCRIPTION
 *   Test the VarBuf ADT.
 * COPYRIGHT
 *   VarBuf - Variable size buffer ADT.
 *   Copyright (C) 1995  Rene W.J. Pijlman
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   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.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * VERSION
 *   /home/rene/sys/CVS_MasterSourceRepository/skim/VarBufTest.c,v 1.7 1995/08/15 19:33:38 rpijlman Exp
 *   Distributed with Skim version 0.6.
 */

#include "VarBuf.h"

#include <stdio.h>
#include <assert.h>

/* assert()'s must be in effect in this file. */
#ifdef NDEBUG
#    undef NDEBUG
#endif

static void TestCreation( VarBuf * Buf1, VarBuf * Buf2 )
{
    *Buf1 = VBCreate();
    *Buf2 = VBCreate();

    assert( VBSize(*Buf1) == 0 );
    assert( VBSize(*Buf2) == 0 );
    assert( strlen( VBAsString(*Buf1) ) == 0 );
    assert( strlen( VBAsString(*Buf2) ) == 0 );
}


static void TestAppendStringAndChar( VarBuf Buf1, VarBuf Buf2 )
{
    VBReset( Buf1 );
    VBReset( Buf2 );

    VBAppendString( Buf1, "Alle" );
    VBAppendCharacter( Buf1, ' ' );
    VBAppendString( Buf2, "eendjes" );
    VBAppendVB( Buf1, Buf2 );
    VBAppendCharacter( Buf1, ' ' );
    VBAppendString( Buf1, "zwemmen" );
    VBAppendCharacter( Buf1, ' ' );
    VBReset( Buf2 );
    VBAppendString( Buf2, "in" );
    VBAppendCharacter( Buf2, ' ' );
    VBAppendString( Buf2, "het" );
    VBAppendVB( Buf1, Buf2 );
    VBAppendCharacter( Buf1, ' ' );
    VBAppendString( Buf1, "water" );

    assert( !strcmp( VBAsString(Buf1), "Alle eendjes zwemmen in het water" ) );
}


static void TestTruncate( VarBuf Buf1, VarBuf Buf2 )
{
    VBReset( Buf1 );
    VBAppendString( Buf1, "ABC" );
    VBTruncate( Buf1, 1 );
    assert( VBSize(Buf1) == 1 );
    assert( !strcmp(VBAsString(Buf1), "A"));

    VBReset( Buf1 );
    VBAppendString( Buf1, "ABC" );
    VBTruncate( Buf1, 0 );
    assert( VBSize(Buf1) == 0 );
    assert( !strcmp(VBAsString(Buf1), ""));

    VBReset( Buf2 );
    VBAppendString( Buf2, "ABC" );
    VBTruncate( Buf2, 3 );
    assert( VBSize(Buf2) == 3 );
    assert( !strcmp(VBAsString(Buf2), "ABC"));
}


#define HUGE 100000

static void TestManyAppends( VarBuf Buf1, VarBuf Buf2 )
{
    int i;
    VBReset( Buf1 );

    for ( i = 0; i < HUGE; i++ )
    {
        VBAppendCharacter( Buf1, 'x' );
    }
    assert( VBSize( Buf1 ) == HUGE );
    assert( strlen( VBAsString( Buf1 ) ) == HUGE );

    for ( i = 0; i < HUGE; i++ )
    {
        assert( VBAsString(Buf1)[i] == 'x' );
    }
}


static void TestShiftLeft( VarBuf Buf1, VarBuf Buf2 )
{
    VBReset( Buf1 );
    VBAppendString( Buf1, "ABC" );
    VBShiftLeft(Buf1, 2);
    assert( VBSize(Buf1) == 1 );
    assert( !strcmp(VBAsString(Buf1), "C"));

    VBReset( Buf1 );
    VBAppendString( Buf1, "ABC" );
    VBShiftLeft(Buf1, 3);
    assert( VBSize(Buf1) == 0 );
    assert( !strcmp(VBAsString(Buf1), ""));

    VBReset( Buf2 );
    VBAppendString( Buf2, "ABC" );
    VBShiftLeft(Buf2, 0);
    assert( VBSize(Buf2) == 3 );
    assert( !strcmp(VBAsString(Buf2), "ABC"));
}


static void TestReadLine( VarBuf Buf1, VarBuf Buf2 )
{
    FILE * Null = NULL;
    FILE * Temp = NULL;

    VBReset( Buf2 );
    Null = fopen( "/dev/null", "r" );
    assert( Null != NULL );
    assert( !VBReadLine( Buf2, Null, True ) );
    assert( VBSize(Buf2) == 0 );

    assert( ( Temp = fopen( "/tmp/VarBufTest.tmp", "w" ) ) != NULL );
    assert( fprintf( Temp, "\n" ) != EOF );
    assert( fclose( Temp ) != EOF );

    assert( ( Temp = fopen( "/tmp/VarBufTest.tmp", "r" ) ) != NULL );
    VBReset( Buf1 );
    VBReadLine( Buf1, Temp, True );
    assert( VBSize( Buf1 ) == 1 );
    assert( !strcmp( VBAsString(Buf1), "\n" ) );

    assert( ( Temp = fopen( "/tmp/VarBufTest.tmp", "r" ) ) != NULL );
    VBReset( Buf1 );
    assert( !strcmp( VBAsString(Buf1), "" ) );
    VBReadLine( Buf1, Temp, False );
    assert( VBSize( Buf1 ) == 0 );
    assert( !strcmp( VBAsString(Buf1), "" ) );
    assert( VBAsString(Buf1) != NULL );
    assert( !strcmp( VBAsString(Buf1), "" ) );

    assert( ( Temp = fopen( "/tmp/VarBufTest.tmp", "w" ) ) != NULL );
    assert( fprintf( Temp, "alt.arts.nomad 0000000757 0000000554 y
\n" ) != EOF );
    assert( fprintf( Temp, "alt.ascii-art 0000023551 21588 y
\n" ) != EOF );
    assert( fprintf( Temp, "alt.ascii-art.animation 0000001209 01109 y
\n" ) != EOF );
    assert( fprintf( Temp, "alt.asian-movies 0000016485 0000013889 y
\n" ) != EOF );
    assert( fclose( Temp ) != EOF );
    assert( ( Temp = fopen( "/tmp/VarBufTest.tmp", "r" ) ) != NULL );
    VBReset( Buf1 );
    VBReadLine( Buf1, Temp, True );
    assert( !strcmp(VBAsString(Buf1), "alt.arts.nomad 0000000757 0000000554 y
\n" ) );
    VBReset( Buf1 );
    VBReadLine( Buf1, Temp, True );
    assert( !strcmp(VBAsString(Buf1), "alt.ascii-art 0000023551 21588 y
\n" ));
    VBReset( Buf1 );
    VBReadLine( Buf1, Temp, True );
    assert( !strcmp(VBAsString(Buf1), "alt.ascii-art.animation 0000001209 01109 y
\n"));
    VBReset( Buf1 );
    VBReadLine( Buf1, Temp, True );
    assert( !strcmp(VBAsString(Buf1), "alt.asian-movies 0000016485 0000013889 y
\n"));

    VBReset( Buf1 );
    VBPrintf( Buf1, "Alle %s %s in %shet %s", "eendjes", "zwemmen", "",
                    "water" );
    assert( !strcmp( VBAsString(Buf1), "Alle eendjes zwemmen in het water" ) );

    VBReset( Buf1 );
    VBReset( Buf2 );
    VBPrintf( Buf2, "zwemmen in" );
    VBPrintf( Buf1, "Alle %s %V het %s", "eendjes", Buf2, "water" );
    assert( !strcmp( VBAsString(Buf1), "Alle eendjes zwemmen in het water" ) );

    system( "rm -f /tmp/VarBufTest.tmp" );
}


int main( void )
{
    VarBuf Buf1;
    VarBuf Buf2;

    TestCreation( &Buf1, &Buf2 );

    TestAppendStringAndChar( Buf1, Buf2 );

    TestManyAppends( Buf1, Buf2 );

    TestTruncate( Buf1, Buf2 );

    TestReadLine( Buf1, Buf2 );

    TestShiftLeft( Buf1, Buf2 );

    VBDestroy( Buf1 );
    VBDestroy( Buf2 );

    printf( "VarBufTest succeeded.\n" );

    return EXIT_SUCCESS;
}
