text: /**
   * These are functional tests for the var_table common module.
   */
  
  // mock all system memory allocation routines
  #define USE_MEMORY 1
  #define USE_CAPTURE 1
  #define VERBOSE 0
  #include "unit_tests.h"
  #include "../mocks/memory_mocks.h"
  
  /*
   * Define the mocks and stubs that are needed for the tests.
   */
  
  #include "str_table.h"
  
  /*
   * Simulate the string table functions. These are tested in the string table
   * tests.
   */
  DEF_MOCK(str_table_t*, create_str_table)
      return malloc(sizeof(str_table_t));
  END_MOCK
  
  DEF_MOCK(void, destroy_str_table, str_table_t* tab)
      free(tab);
  END_MOCK
  
  DEF_MOCK(int, add_string, str_table_t* tab, const char* str)
      (void)tab;
      printf("MSG: string add mock: \"%s\"\n", str);
      return 0;
  END_MOCK
  
  #include "var_table.h"
  #include "../var_table.c"
  
  /*
   * Define the tests.
   */
  
  /*
   * var_table_t* create_var_table();
   */
  DEF_TEST(test_create_var_table)
  
      assert_memory_pool_size(0);
  
      var_table_t* vt = create_var_table();
  
      assert_ptr_not_null(vt);
      assert_uint_equal(vt->capacity, 0x08);
      assert_uint_equal(vt->length, 0);
      assert_ptr_not_null(vt->table);
      assert_ptr_not_null(vt->strs);
      assert_mock_entered("create_str_table");
      assert_memory_pool_size(96);
      //assert_mock_entered_count(2, "memory_calloc");
      assert_calloc_entered_count(2);
  
  END_TEST
  
  /*
   * void destroy_var_table(var_table_t*);
   */
  DEF_TEST(test_destroy_var_table)
  
      assert_memory_pool_size(0);
  
      destroy_var_table(NULL);
      assert_free_entered_count(0);
  
      var_table_t* vt = create_var_table();
      assert_ptr_not_null(vt);
      assert_memory_pool_size(96);
  
      destroy_var_table(vt);
      assert_free_entered_count(3);
  
  END_TEST
  
  /*
   * var_t* create_var(var_table_t*, int*, var_type_t);
   */
  DEF_TEST(test_create_var)
  
      assert_memory_pool_size(0);
  
      var_table_t* vt = create_var_table();
      int idx = 0;
      var_t* var;
      assert_memory_pool_size(96);
  
      // create_var() called exit() so it has to be captured.
      CAPTURE
          var = create_var(vt, &idx, VT_UNUM);
      END_CAPTURE
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(1, vt->length);
      assert_int_equal(VT_UNUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_false(var->is_init);
      assert_memory_pool_size(96);
  
      CAPTURE
          var = create_var(vt, &idx, VT_INUM);
      END_CAPTURE
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(2, vt->length);
      assert_int_equal(VT_INUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_false(var->is_init);
  
      CAPTURE
          var = create_var(vt, &idx, VT_FNUM);
      END_CAPTURE
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(3, vt->length);
      assert_int_equal(VT_FNUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_false(var->is_init);
  
      CAPTURE
          var = create_var(vt, &idx, VT_BOOL);
      END_CAPTURE
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(4, vt->length);
      assert_int_equal(VT_BOOL, var->type);
      assert_bool_true(var->in_use);
      assert_bool_false(var->is_init);
  
      CAPTURE
          var = create_var(vt, &idx, VT_ADDR);
      END_CAPTURE
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(5, vt->length);
      assert_int_equal(VT_ADDR, var->type);
      assert_bool_true(var->in_use);
      assert_bool_false(var->is_init);
  
      CAPTURE
          var = create_var(vt, &idx, VT_UNUM);
      END_CAPTURE
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(6, vt->length);
      assert_int_equal(VT_UNUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_false(var->is_init);
  
      CAPTURE
          var = create_var(vt, &idx, VT_INUM);
      END_CAPTURE
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(7, vt->length);
      assert_int_equal(VT_INUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_false(var->is_init);
  
      CAPTURE
          var = create_var(vt, &idx, VT_FNUM);
      END_CAPTURE
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(8, vt->length);
      assert_int_equal(VT_FNUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_false(var->is_init);
  
      // Note that the capacity changed
      CAPTURE
          var = create_var(vt, &idx, VT_BOOL);
      END_CAPTURE
      assert_uint_equal(0x10, vt->capacity);
      assert_uint_equal(9, vt->length);
      assert_int_equal(VT_BOOL, var->type);
      assert_bool_true(var->in_use);
      assert_bool_false(var->is_init);
      assert_memory_pool_size(336);
  
      CAPTURE
          var = create_var(vt, &idx, VT_ADDR);
      END_CAPTURE
      assert_uint_equal(0x10, vt->capacity);
      assert_uint_equal(10, vt->length);
      assert_int_equal(VT_ADDR, var->type);
      assert_bool_true(var->in_use);
      assert_bool_false(var->is_init);
  
      destroy_var_table(vt);
      assert_free_entered_count(3);
  
  END_TEST
  
  /*
   * int create_unum_var(var_table_t*, uint64_t);
   */
  DEF_TEST(test_create_unum_var)
  
      assert_memory_pool_size(0);
  
      var_table_t* vt = create_var_table();
      int idx = 0;
      var_t* var;
      assert_memory_pool_size(96);
  
      CAPTURE
          idx = create_unum_var(vt, 0);
      END_CAPTURE
      assert_int_equal(0, idx);
      var = get_var_ptr(vt, idx);
      assert_int_equal(VT_UNUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_true(var->is_init);
      assert_uint_equal(0, var->val.unum);
  
      CAPTURE
          idx = create_unum_var(vt, 0x1234);
      END_CAPTURE
      assert_int_equal(1, idx);
      var = get_var_ptr(vt, idx);
      assert_int_equal(VT_UNUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_true(var->is_init);
      assert_uint_equal(0x1234, var->val.unum);
  
      assert_malloc_entered_count(1);
      assert_calloc_entered_count(2);
      assert_realloc_not_entered();
      assert_free_not_entered();
  
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(2, vt->length);
  
      destroy_var_table(vt);
      assert_free_entered_count(3);
  
  END_TEST
  
  /*
   * int create_inum_var(var_table_t*, int64_t);
   */
  DEF_TEST(test_create_inum_var)
  
      assert_memory_pool_size(0);
  
      var_table_t* vt = create_var_table();
      int idx = 0;
      var_t* var;
      assert_memory_pool_size(96);
  
      CAPTURE
          idx = create_inum_var(vt, 430);
      END_CAPTURE
      assert_int_equal(0, idx);
      var = get_var_ptr(vt, idx);
      assert_int_equal(VT_INUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_true(var->is_init);
      assert_int_equal(430, var->val.inum);
  
      CAPTURE
          idx = create_inum_var(vt, -12);
      END_CAPTURE
      assert_int_equal(1, idx);
      var = get_var_ptr(vt, idx);
      assert_int_equal(VT_INUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_true(var->is_init);
      assert_int_equal(-12, var->val.inum);
  
      assert_malloc_entered_count(1);
      assert_calloc_entered_count(2);
      assert_realloc_not_entered();
      assert_free_not_entered();
  
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(2, vt->length);
  
      destroy_var_table(vt);
      assert_free_entered_count(3);
  
  END_TEST
  
  /*
   * int create_fnum_var(var_table_t*, double);
   */
  DEF_TEST(test_create_fnum_var)
  
      assert_memory_pool_size(0);
  
      var_table_t* vt = create_var_table();
      int idx = 0;
      var_t* var;
      assert_memory_pool_size(96);
  
      CAPTURE
          idx = create_fnum_var(vt, 0);
      END_CAPTURE
      assert_int_equal(0, idx);
      var = get_var_ptr(vt, idx);
      assert_int_equal(VT_FNUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_true(var->is_init);
      assert_double_equal(0.0, var->val.fnum, 0.001);
  
      CAPTURE
          idx = create_fnum_var(vt, 1234.432);
      END_CAPTURE
      assert_int_equal(1, idx);
      var = get_var_ptr(vt, idx);
      assert_int_equal(VT_FNUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_true(var->is_init);
      assert_double_equal(1234.432, var->val.fnum, 0.001);
  
      assert_malloc_entered_count(1);
      assert_calloc_entered_count(2);
      assert_realloc_not_entered();
      assert_free_not_entered();
  
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(2, vt->length);
  
      destroy_var_table(vt);
      assert_free_entered_count(3);
  
  END_TEST
  
  /*
   * int create_bool_var(var_table_t*, bool);
   */
  DEF_TEST(test_create_bool_var)
  
      assert_memory_pool_size(0);
  
      var_table_t* vt = create_var_table();
      int idx = 0;
      var_t* var;
      assert_memory_pool_size(96);
  
      CAPTURE
          idx = create_bool_var(vt, true);
      END_CAPTURE
      assert_int_equal(0, idx);
      var = get_var_ptr(vt, idx);
      assert_int_equal(VT_BOOL, var->type);
      assert_bool_true(var->in_use);
      assert_bool_true(var->is_init);
      assert_bool_true(var->val.boolean);
  
      CAPTURE
          idx = create_bool_var(vt, false);
      END_CAPTURE
      assert_int_equal(1, idx);
      var = get_var_ptr(vt, idx);
      assert_int_equal(VT_BOOL, var->type);
      assert_bool_true(var->in_use);
      assert_bool_true(var->is_init);
      assert_bool_false(var->val.boolean);
  
      assert_malloc_entered_count(1);
      assert_calloc_entered_count(2);
      assert_realloc_not_entered();
      assert_free_not_entered();
  
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(2, vt->length);
  
      destroy_var_table(vt);
      assert_free_entered_count(3);
  
  END_TEST
  
  
  /*
   * void delete_var(var_table_t*, int);
   */
  DEF_TEST(test_delete_var)
  
      assert_memory_pool_size(0);
  
      var_table_t* vt = create_var_table();
      var_t* var;
      int idx;
      assert_memory_pool_size(96);
  
      CAPTURE
          create_bool_var(vt, true);
          create_bool_var(vt, false);
          create_bool_var(vt, true);
      END_CAPTURE
      assert_uint_equal(3, vt->length);
  
      var = get_var_ptr(vt, 0);
      assert_int_equal(VT_BOOL, var->type);
      assert_bool_true(var->in_use);
      assert_bool_true(var->is_init);
      assert_bool_true(var->val.boolean);
  
      var = get_var_ptr(vt, 1);
      assert_int_equal(VT_BOOL, var->type);
      assert_bool_true(var->in_use);
      assert_bool_true(var->is_init);
      assert_bool_false(var->val.boolean);
  
      var = get_var_ptr(vt, 2);
      assert_int_equal(VT_BOOL, var->type);
      assert_bool_true(var->in_use);
      assert_bool_true(var->is_init);
      assert_bool_true(var->val.boolean);
  
      // delete the middle var
      CAPTURE
          delete_var(vt, 1);
      END_CAPTURE
      // The only change is that in_use is now false
      var = get_var_ptr(vt, 1);
      assert_int_equal(VT_BOOL, var->type);
      assert_bool_false(var->in_use);
      assert_bool_true(var->is_init);
      assert_bool_false(var->val.boolean);
  
      // now add another var and it should be in slot 1
      CAPTURE
          idx = create_fnum_var(vt, 8.987);
      END_CAPTURE
      assert_int_equal(1, idx);
      var = get_var_ptr(vt, idx);
      assert_int_equal(VT_FNUM, var->type);
      assert_bool_true(var->in_use);
      assert_bool_true(var->is_init);
      assert_double_equal(8.987, var->val.fnum, 0.001);
  
      assert_malloc_entered_count(1);
      assert_calloc_entered_count(2);
      assert_realloc_not_entered();
      assert_free_not_entered();
  
      assert_uint_equal(0x08, vt->capacity);
      assert_uint_equal(3, vt->length);
  
      destroy_var_table(vt);
      assert_free_entered_count(3);
  
  END_TEST
  
  /*
   * void save_var_table(FILE*);
   *
   * This is not implemented yet
   */
  DEF_TEST(test_save_var_table)
  
      unit_msg(3, "Not implemented");
  
  END_TEST
  
  /*
   * var_table_t* load_var_table(FILE*);
   *
   * This is not implemented yet
   */
  DEF_TEST(test_load_var_table)
  
      unit_msg(3, "Not implemented");
  
  END_TEST
  
  /*
   * test main()
   */
  DEF_TEST_MAIN("var_table functional unit tests")
  
      // TRACK_MEMORY_MOCKS
      // TRACK_EXIT_MOCK
  
      TRACK_MOCK("create_str_table");
      TRACK_MOCK("destroy_str_table");
      TRACK_MOCK("add_string");
  
      ADD_TEST(test_create_var_table);
      ADD_TEST(test_destroy_var_table);
      ADD_TEST(test_create_var);
      ADD_TEST(test_create_unum_var);
      ADD_TEST(test_create_inum_var);
      ADD_TEST(test_create_fnum_var);
      ADD_TEST(test_create_bool_var);
      ADD_TEST(test_delete_var);
      ADD_TEST(test_save_var_table);
      ADD_TEST(test_load_var_table);
  
  END_TEST_MAIN
  