/*
    test_bigint.c - Testcase for big positive integer numbers
    Copyright (c) 2005  Martin Schulze <joey@infodrom.org>

    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.

    $Id$
 */

#include "bigint.h"
#include <stdio.h>
#include <string.h>

int nrtest = 0;

int compare (bigint is, char *should)
{
  char s[30];

  nrtest++;
  bigint_sprintf (s, "%s", is);

  if (!strcmp(s, should)) {
    printf ("Test %d passed, %s == %s\n", nrtest, s, should);
    return 1;
  } else {
    fprintf (stderr, "Test %d failed, %s != %s\n", nrtest, s, should);
    return 0;
  }
}

int main()
{
  bigint foo, bar, baz;
  char s[20];
  int passed = 0;
  int i;

  /* Test 1: Representing zero */
  foo = bigint_int (0);
  passed += compare (foo, "0");

  /* Test 2: Representing nonzero */
  foo = bigint_int (654321);
  passed += compare (foo, "654321");

  /* Test 3: Representing BIGINT_MAX */
  foo = bigint_int (BIGINT_MAX);
  sprintf (s, "%d", BIGINT_MAX);
  passed += compare (foo, s);

  /* Test 4: BIGINT_MAX + 1 */
  foo = bigint_int (BIGINT_MAX);
  bar = bigint_int (1);
  baz = bigint_add (foo, bar);
  sprintf (s, "%d", BIGINT_MAX);
  s[strlen(s)-1] = '1';
  passed += compare (baz, s);

  /* Test 5: BIGINT_MAX - 1 */
  foo = bigint_int (BIGINT_MAX);
  bar = bigint_int (1);
  baz = bigint_sub (foo, bar);
  sprintf (s, "%d", BIGINT_MAX);
  for (i=0;s[i];i++) s[i] = '9';
  s[strlen(s)-1] = '\0';
  passed += compare (baz, s);

  /* Test 6: BIGINT_MAX + 1 -1 */
  foo = bigint_int (BIGINT_MAX);
  bar = bigint_int (1);
  baz = bigint_add (foo, bar);
  foo = bigint_sub (baz, bar);
  sprintf (s, "%d", BIGINT_MAX);
  passed += compare (foo, s);

  /* Test 7: BIGINT_MAX + 1234 */
  foo = bigint_int (BIGINT_MAX);
  bar = bigint_int (1234);
  baz = bigint_add (foo, bar);
  sprintf (s, "%d", BIGINT_MAX);
  sprintf (s+6, "%d", 1234);
  passed += compare (baz, s);

  /* Test 8: BIGINT_MAX + 1234 - 1234 */
  foo = bigint_sub (baz, bar);
  sprintf (s, "%d", BIGINT_MAX);
  passed += compare (foo, s);

  /* Test 9: BIGINT_MAX - 100000000 */
  foo = bigint_int (BIGINT_MAX);
  bar = bigint_int (100000000);
  baz = bigint_sub (foo, bar);
  sprintf (s, "%d", 900000000);
  passed += compare (baz, s);

  /* Test 10: BIGINT_MAX + BIGINT_MAX */
  foo = bigint_int (BIGINT_MAX);
  baz = bigint_add (foo, foo);
  sprintf (s, "%d", BIGINT_MAX);
  s[0] = '2';
  passed += compare (baz, s);

  /* Test 11: BIGINT_MAX - BIGINT_MAX */
  foo = bigint_int (BIGINT_MAX);
  baz = bigint_sub (foo, foo);
  passed += compare (baz, "0");

  /* Test 12: BIGINT_MAX + ( BIGINT_MAX -1) */
  foo = bigint_int (BIGINT_MAX);
  baz = bigint_sub (foo, foo);
  passed += compare (baz, "0");

  /* Test 13: BIGINT_MAX-1 + 1 */
  foo = bigint_int (BIGINT_MAX-1);
  bar = bigint_int (1);
  baz = bigint_add (foo, bar);
  sprintf (s, "%d", BIGINT_MAX);
  passed += compare (baz, s);

  /* Test 14: BIGINT_MAX-1 + 2 */
  foo = bigint_int (BIGINT_MAX-1);
  bar = bigint_int (2);
  baz = bigint_add (foo, bar);
  sprintf (s, "%d", BIGINT_MAX);
  s[strlen(s)-1] = '1';
  passed += compare (baz, s);

  /* Test 15: BIGINT_MAX + BIGINT_MAX-1 */
  foo = bigint_int (BIGINT_MAX);
  bar = bigint_int (BIGINT_MAX-1);
  baz = bigint_add (foo, bar);
  sprintf (s, "%d", BIGINT_MAX);
  for (i=1;s[i];i++) s[i]='9';
  passed += compare (baz, s);


  printf ("%d tests passed\n", passed);
  if (passed < nrtest) printf ("%d tests failed\n", nrtest-passed);
  return 0;
}
