Files @ 2d956d549430
Branch filter:

Location: DistRen/test/check_csv.c

binki
Add simple CSV parser for normaldotcom.
/*
 * Copyright 2010 Nathan Phillip Brink
 *
 * This file is a part of DistRen.
 *
 * DistRen is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * DistRen 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with DistRen.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "common/csv.h"

#include <check.h>
#include <list.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct check_correct_vals
{
  size_t row;
  size_t num_cols;
  char ***correct_vals;
};

static void **array_init(size_t num_elems, ...)
{
  va_list args;
  void **array;
  size_t c;

  array = malloc(sizeof(void *) * (num_elems + 1));
  if (!array)
    return NULL;

  va_start(args, num_elems);

  for (c = 0; c < num_elems; c ++)
    array[c] = va_arg(args, void *);
  array[c] = NULL;

  va_end(args);

  return array;
}

static int check_correct_vals(struct check_correct_vals *state, csv_row_t row)
{
  size_t c;

  fail_unless (state->num_cols == row->num_cols,
	       "We asked for %d columns but got %d on row %d",
	       state->num_cols, row->num_cols, state->row);

  for (c = 0; c < row->num_cols; c ++)
    {
      fail_if(strcmp(state->correct_vals[state->row][c],
		     row->cols[c]),
	      "%d:%d: Expecting %s: got %s",
	      state->row, c,
	      state->correct_vals[state->row][c],
	      row->cols[c]
	      );
    }

  state->row ++;
  if (state->correct_vals[state->row])
    /* there is yet another row to process */
    return TRUE;
  return FALSE;
}

START_TEST(check_csv)
{
  list_t rows;
  struct check_correct_vals vals;

  char ***correct_vals;
  
  correct_vals =
    (char ***)array_init(4,
			 array_init(3, "23", "1" , "0.0"),
			 array_init(3, "a" , " b", ""   ),
			 array_init(3, "f" , "df", ""   ),
			 array_init(3, "d" , "f" , "ss" ));
  fail_if(correct_vals == NULL, "array_init() returned NULL");

  vals.num_cols = 3;
  vals.correct_vals = correct_vals;
  vals.row = 0;

  rows = csv_parse("23,1,0.0\n\
a, b,,d\n\
f,df\n\
d,f,ss,e\n", vals.num_cols);
  fail_if(rows == NULL, "csv_parse() returned NULL");
  list_traverse(rows, &vals, (list_traverse_func_t)&check_correct_vals, LIST_FRNT|LIST_SAVE|LIST_FORW);

  list_free(rows, (list_dealloc_func_t)&csv_row_free);
}
END_TEST

static Suite *csv_suite()
{
  Suite *s;
  TCase *tc;

  s = suite_create("csv");

  tc = tcase_create("core");
  tcase_add_test(tc, check_csv);
  suite_add_tcase(s, tc);

  return s;
}

int main(int argc, char *argv[])
{
  int number_failed;
  Suite *s;
  SRunner *sr;

  s = csv_suite();
  sr = srunner_create(s);

  srunner_run_all(sr, CK_NORMAL);
  number_failed = srunner_ntests_failed(sr);
  srunner_free(sr);

  if (number_failed)
    return EXIT_FAILURE;
  return EXIT_SUCCESS;
}