#include <stdbool.h>
#include <stdio.h>

#include "listarray.h"

#define TEST(EXPR,RESULT)                                                     \
        if ((EXPR) != (RESULT)) {                                             \
          ++numErrors;                                                        \
          printf("Did not get expected result %s for %s.\n", #RESULT, #EXPR); \
        }

/* Print a report of a collection of unit tests.
 * Prints OK when no errors and FAIL with a count otherwise.
 */
void
reportTests (int numErrors)
{
  if (numErrors>0)
    printf (" FAIL: %d errors\n",numErrors);
  else
    printf (" OK\n");
} // reportTests


/* Test collection example */
int
testExample (void)
{
  printf("--EXAMPLE TEST--");

  int numErrors = 0;
  
  listarray_t * list = create (5);

  TEST( size (list),   0 );   // list is empty
  TEST( add (list,42), true); // added item
  TEST( size (list),   1 );   // list is appropriate size
  TEST( get (list,0),  42);   // check item was added / indexable

  clear(list);
  
  reportTests (numErrors);
  return numErrors;
} // testExample


/* Test all methods for a single node (no expansions) */
int
testBasic (void)
{
  printf("--BASIC TESTS--");
  
  const unsigned int CAPACITY = 10;
  int numErrors = 0;
 
  listarray_t * list = create (CAPACITY);

  TEST( size(list), 0 );        // initial list is empty

  int i; // index for all loops
  
  /* Test add (successful), size (incremented), and get (new item) */
  for (i=0 ; i<CAPACITY ; i++) {
    TEST( add (list,i), true);  // added item i
    TEST( size (list),  i+1 );  // list is appropriate size
    TEST( get (list,i), i);     // check index i is item i
  }

  /* Test contains (true and false) at all locations*/
  for (i=0 ; i< 2*CAPACITY ; i++) {
    TEST( contains (list,i), i<CAPACITY); // list contains item
  }

  /* Test set (return), size (same), and get (new value) */
  for ( i=0 ; i<CAPACITY ; i++) {
    TEST( set (list, i, i + CAPACITY), i);
    TEST( size (list), CAPACITY ) ;
    TEST( get (list,i), i + CAPACITY); 
  }

  clear (list); // should run without memory errors
  
  reportTests (numErrors);
  return numErrors;
} // testBasic


/* Test all functionality by running test functions.
 * Returns the total number of errors.
*/
int
testAll (void)
{
  int numErrors = 0;

  numErrors += testExample();
  numErrors += testBasic();
  // Add more test collections here

  if (numErrors==0)
    printf ("TESTS PASSED\n");
  else
    printf ("TOTAL ERRORS: %d\n",numErrors);
  return numErrors;
  
} // testAll


/* Driver program for test suite */
int
main (void)
{
  return testAll();
} // main
