#include <stdlib.h>
#include "cunit/unit.h"
#include "util.h"

static void test_null(void)
{
    char *s;

    s = strconcat((char *)NULL);
    CU_ASSERT_PTR_NULL(s);
}

static void test_single(void)
{
    static const char word1[] = "lorem";
    char *s;

    s = strconcat(word1, (char *)NULL);
    CU_ASSERT_PTR_NOT_NULL(s);
    CU_ASSERT_STRING_EQUAL(s, "lorem");
    free(s);
}

static void test_multiple(void)
{
    static const char word1[] = "lorem";
    static const char word2[] = "ipsum";
    static const char word3[] = "dolor";
    static const char word4[] = "sit";
    static const char word5[] = "amet";
    static const char word6[] = "consectetur adipisicing elit";
    char *s;

    s = strconcat(word1, " ", word2, " ", word3, " ",
                  word4, " ", word5, ", ", word6,
                  (char *)NULL);
    CU_ASSERT_PTR_NOT_NULL(s);
    CU_ASSERT_STRING_EQUAL(s, "lorem ipsum dolor sit amet, consectetur adipisicing elit");
    free(s);
}

static void test_uncast_null(void)
{
    static const char word1[] = "foo";
    static const char word2[] = "bar";
    char *s;

    /*
     * On some platforms, a combination of the ABI model, default
     * type of the "NULL" define, and the behaviour of varargs
     * can screw up the usage of an uncast NULL as a terminator.
     * This will tell us if we're on one of those.
     */
    s = strconcat(word1, NULL, word2, (char *)NULL);
    CU_ASSERT_PTR_NOT_NULL(s);
    CU_ASSERT_STRING_EQUAL(s, "foo");
    free(s);
}

/* This doesn't really belong in this .c file
 * but it's the least worst choice */
static void test_strcmpsafe(void)
{
    /* chosen so word1 < word2 lexically */
    static const char word1[] = "bar";
    static const char word2[] = "foo";

    /* basic behaviour is identical to strcmp() */
    CU_ASSERT_EQUAL(strcmpsafe(word1, word1), 0);
    CU_ASSERT_EQUAL(strcmpsafe(word2, word2), 0);
    CU_ASSERT(strcmpsafe(word1, word2) < 0);
    CU_ASSERT(strcmpsafe(word2, word1) > 0);

    /* but it's safe with NULLs */
    CU_ASSERT_EQUAL(strcmpsafe(NULL, NULL), 0);
    CU_ASSERT_EQUAL(strcmpsafe("", NULL), 0);
    CU_ASSERT_EQUAL(strcmpsafe(NULL, ""), 0);
    CU_ASSERT(strcmpsafe(word1, NULL) > 0);
    CU_ASSERT(strcmpsafe(word2, NULL) > 0);
    CU_ASSERT(strcmpsafe(NULL, word1) < 0);
    CU_ASSERT(strcmpsafe(NULL, word2) < 0);
}
/* vim: set ft=c: */
