/* $Id: vercmp.c,v 1.3 2002/06/23 20:28:31 richdawe Exp $ */

/*
 * vercmp.c - Test program for pakke's package_vercmp*() functions
 * Copyright (C) 2001, 2002 by Richard Dawe
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <libpakke/package.h>

/* Sanity checks */
#if PACKAGE_VERSION_N_HAS != 14
#error "Need to update test to cope with PACKAGE_VERSION's has_*"
#endif

#if PACKAGE_VERSION_N_DATA != 21
#error "Need to update test to cope with PACKAGE_VERSION's data fields"
#endif

/* Types for formulating test cases */
typedef enum {
  EQUAL        =  0,
  LESS_THAN    = -1,
  GREATER_THAN =  1
} comparison_t;

typedef struct {
  struct {
    const char *ver_str; /* Textual representation, for display */
    PACKAGE_VERSION ver; /* Actual encoded version */
  } vers[2];

  /* Expected result of comparison of vers[0] - vers[1] */
  const comparison_t expect_comp;
} vercmp_testcase_t;

/* Test cases */
vercmp_testcase_t testcases[] = {
  /* Less than, with leading zero */
  {
    {
      {
	"1",
	{
	  1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      },
      {
	"1.0",
	{
	  1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      }      
    },
    LESS_THAN
  },

  /* Equality */
  {
    {
      {
	"1",
	{
	  1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      },
      {
	"1",
	{
	  1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      }      
    },
    EQUAL
  },

  /* Missing - precedence set 1 (see src/libpakke/package.c for
   * definition). */
  {
    {
      {
	"1",
	{
	  1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      },
      {
	"1.0",
	{
	  1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      }
    },
    LESS_THAN
  },

  /* Missing - precedence set 2 (see src/libpakke/package.c for
   * definition). */
  {
    {
      {
	"1",
	{
	  1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      },
      {
	"1 alpha 1",
	{
	  1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 1, /* alpha */
	  0, 0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      }
    },
    GREATER_THAN
  },

  /* Missing - precedence set 2 (see src/libpakke/package.c for
   * definition). */
  {
    {      
      {
	"1 beta 1",
	{
	  1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 1, /* beta */
	  0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}	
      },
      {
	"1",
	{
	  1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      }
    },
    LESS_THAN
  },

  /* Missing - precedence set 2 (see src/libpakke/package.c for
   * definition). */
  {
    {      
      {
	"1 pre 1",
	{
	  1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 0, 1, /* pre */
	  0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      },
      {
	"1",
	{
	  1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      }
    },
    LESS_THAN
  },

  /* Different versions in precedence set 2 (see src/libpakke/package.c for
   * definition). */
  {
    {
      {
	"1 alpha 1",
	{
	  1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 1, /* alpha */
	  0, 0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      },
      {
	"1 beta 1",
	{
	  1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 1, /* beta */
	  0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}	
      }
    },
    LESS_THAN
  },

  /* Different versions in precedence set 2 (see src/libpakke/package.c for
   * definition). */
  {
    {      
      {
	"1 beta 1",
	{
	  1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 1, /* beta */
	  0, 0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}	
      },
      {
	"1 pre 1",
	{
	  1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, /* has_* */
	  1, 0, /* major, minor */
	  0, 0, 0, 0, 0, 0, 0, 1, /* pre */
	  0, 0, 0, 0, 0, 0, /* int ver. components */
	  NULL, NULL, NULL, NULL, /* platform components */
	  TYPE_BINARIES
	}
      }
    },
    LESS_THAN
  }

  /* TODO: Test comparisons different number of leading zeroes */
};

int
main (int argc, char *argv[])
{
  int n_testcases = sizeof(testcases) / sizeof(testcases[0]);
  int i;
  int quiet = 0;

  /* Parse arguments. */
  for (i = 1; i < argc; i++) {
    /* Quiet operation, for automatic testing. */
    if (   (strcmp(argv[i], "--quiet") == 0)
	|| (strcmp(argv[i], "-q") == 0))
      quiet = 1;
  }

  /* Run through the test cases. */
  for (i = 0; i < n_testcases; i++) {
    comparison_t comp;
    int ret;

    if (!quiet) {
      printf("Test case %i: %s", i + 1,
	     package_version_string(&testcases[i].vers[0].ver));
      printf(" - %s\n",
	     package_version_string(&testcases[i].vers[1].ver));
    }

    ret = package_vercmp(&testcases[i].vers[0].ver, &testcases[i].vers[1].ver);

    if (ret < 0)
      comp = LESS_THAN;
    else if (ret > 0)
      comp = GREATER_THAN;
    else
      comp = EQUAL;

    if (comp != testcases[i].expect_comp) {
      if (!quiet) {
	printf("Version comparison gave unexpected result for test case %i: ",
	       i + 1);
	switch(comp) {
	case EQUAL:        puts("EQUAL");        break;
	case LESS_THAN:    puts("LESS_THAN");    break;
	case GREATER_THAN: puts("GREATER_THAN"); break;
	}
      }
      return(EXIT_FAILURE);
    }
  }

  return(EXIT_SUCCESS);
}
