view c/buf/buf-test.c @ 667:325be9bbc68f

buf: initial import
author David Demelier <markand@malikania.fr>
date Fri, 21 Feb 2020 15:09:53 +0100
parents
children
line wrap: on
line source

/*
 * test.c -- test basic buffers
 *
 * Copyright (c) 2016-2019 David Demelier <markand@malikania.fr>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#define GREATEST_USE_ABBREVS 0
#include <greatest.h>

#include "buf.h"

GREATEST_TEST
init(void)
{
	struct buf b;

	/* No allocation with buf_init. */
	buf_init(&b);
	GREATEST_ASSERT(!b.data);
	GREATEST_ASSERT(!b.capacity);
	GREATEST_ASSERT(!b.length);

	/* Must stay zero'ed. */
	buf_finish(&b);
	GREATEST_ASSERT(!b.data);
	GREATEST_ASSERT(!b.capacity);
	GREATEST_ASSERT(!b.length);

	GREATEST_PASS();
}

GREATEST_SUITE(basics)
{
	GREATEST_RUN_TEST(init);
}

GREATEST_TEST
reserve(void)
{
	struct buf b;

	/* Reserve allocates but does not change length. */
	buf_init(&b);
	buf_reserve(&b, 100U);
	GREATEST_ASSERT(b.data);
	GREATEST_ASSERT_EQ(b.length, 0U);
	GREATEST_ASSERT_EQ(b.capacity, 100U);
	buf_finish(&b);

	GREATEST_PASS();
}

GREATEST_TEST
resize(void)
{
	struct buf b;

	/* Resize actually change the length with the specified character. */
	buf_init(&b);
	buf_resize(&b, 10, 'a');
	GREATEST_ASSERT_STR_EQ(b.data, "aaaaaaaaaa");
	GREATEST_ASSERT_EQ(b.length, 10U);
	GREATEST_ASSERT_EQ(b.capacity, 10U);
	buf_finish(&b);

	GREATEST_PASS();
}

GREATEST_TEST
shrink(void)
{
	struct buf b;

	/* Reserve and then shrink, it should be 0. */
	buf_init(&b);
	buf_reserve(&b, 10U);
	buf_shrink(&b);
	GREATEST_ASSERT(b.data);
	GREATEST_ASSERT_EQ(b.length, 0U);
	GREATEST_ASSERT_EQ(b.capacity, 0U);
	buf_finish(&b);

	GREATEST_PASS();
}

GREATEST_SUITE(allocs)
{
	GREATEST_RUN_TEST(reserve);
	GREATEST_RUN_TEST(resize);
}

GREATEST_TEST
output_char(void)
{
	struct buf b;

	buf_init(&b);

	/* This will allocate one byte and then increase by power of two. */
	buf_putc(&b, 'a');
	GREATEST_ASSERT_STR_EQ(b.data, "a");
	GREATEST_ASSERT_EQ(b.length, 1U);
	GREATEST_ASSERT_EQ(b.capacity, 1U);

	buf_putc(&b, 'b');
	GREATEST_ASSERT_STR_EQ(b.data, "ab");
	GREATEST_ASSERT_EQ(b.length, 2U);
	GREATEST_ASSERT_EQ(b.capacity, 2U);

	buf_putc(&b, 'c');
	GREATEST_ASSERT_STR_EQ(b.data, "abc");
	GREATEST_ASSERT_EQ(b.length, 3U);
	GREATEST_ASSERT_EQ(b.capacity, 4U);

	/* No reallocation since there is still one byte left. */
	buf_putc(&b, 'd');
	GREATEST_ASSERT_STR_EQ(b.data, "abcd");
	GREATEST_ASSERT_EQ(b.length, 4U);
	GREATEST_ASSERT_EQ(b.capacity, 4U);

	/* New reallocation here. */
	buf_putc(&b, 'e');
	GREATEST_ASSERT_STR_EQ(b.data, "abcde");
	GREATEST_ASSERT_EQ(b.length, 5U);
	GREATEST_ASSERT_EQ(b.capacity, 8U);
	buf_finish(&b);

	GREATEST_PASS();
}

GREATEST_TEST
output_string(void)
{
	struct buf b;

	buf_init(&b);

	/* This will allocate an initial buffer of 10. */
	buf_puts(&b, "abcdefghij");
	GREATEST_ASSERT_STR_EQ(b.data, "abcdefghij");
	GREATEST_ASSERT_EQ(b.length, 10U);
	GREATEST_ASSERT_EQ(b.capacity, 10U);

	/* This will multiply the capacity to 20 and increase length to 14. */
	buf_puts(&b, "klmn");
	GREATEST_ASSERT_STR_EQ(b.data, "abcdefghijklmn");
	GREATEST_ASSERT_EQ(b.length, 14U);
	GREATEST_ASSERT_EQ(b.capacity, 20U);
	buf_finish(&b);

	GREATEST_PASS();
}

GREATEST_TEST
output_printf(void)
{
	struct buf b;

	buf_init(&b);

	/* This will allocate string of 6 characters. */
	buf_printf(&b, "%d%d", 123, 456);
	GREATEST_ASSERT_STR_EQ(b.data, "123456");
	GREATEST_ASSERT_EQ(b.length, 6U);
	GREATEST_ASSERT_EQ(b.capacity, 6U);

	/* This will multiply the capacity to 12 and increase length to 10. */
	buf_printf(&b, "%s", "hoho");
	GREATEST_ASSERT_STR_EQ(b.data, "123456hoho");
	GREATEST_ASSERT_EQ(b.length, 10U);
	GREATEST_ASSERT_EQ(b.capacity, 12U);
	buf_finish(&b);

	GREATEST_PASS();
}

GREATEST_SUITE(output)
{
	GREATEST_RUN_TEST(output_char);
	GREATEST_RUN_TEST(output_string);
	GREATEST_RUN_TEST(output_printf);
}

GREATEST_TEST
clones_sub(void)
{
	struct buf b = { 0 };
	struct buf s1, s2;

	buf_puts(&b, "0123456789");

	/* Copy only the portion from 1 to 3. */
	buf_sub(&s1, &b, 1, 3);
	GREATEST_ASSERT_STR_EQ(s1.data, "123");
	GREATEST_ASSERT_EQ(s1.length, 3U);
	GREATEST_ASSERT_EQ(s1.capacity, 3U);
	buf_finish(&s1);

	/* Copy whole string starting from 4. */
	buf_sub(&s2, &b, 4, -1);
	GREATEST_ASSERT_STR_EQ(s2.data, "456789");
	GREATEST_ASSERT_EQ(s2.length, 6U);
	GREATEST_ASSERT_EQ(s2.capacity, 6U);
	buf_finish(&s2);
	buf_finish(&b);

	GREATEST_PASS();
}

GREATEST_TEST
clones_dup(void)
{
	struct buf b = { 0 };
	struct buf d;

	buf_puts(&b, "0123456789");
	buf_dup(&d, &b);
	GREATEST_ASSERT(b.data != d.data);
	GREATEST_ASSERT_STR_EQ(d.data, "0123456789");
	GREATEST_ASSERT_EQ(d.length, 10U);
	GREATEST_ASSERT_EQ(d.capacity, 10U);
	buf_finish(&d);

	GREATEST_PASS();
}

GREATEST_SUITE(clones)
{
	GREATEST_RUN_TEST(clones_sub);
	GREATEST_RUN_TEST(clones_dup);
}

GREATEST_TEST
misc_erase(void)
{
	struct buf b = { 0 };

	buf_puts(&b, "0123456789");

	/* Only remove portion from 1 to 3, capacity must not change. */
	buf_erase(&b, 1, 3);
	GREATEST_ASSERT_STR_EQ(b.data, "0456789");
	GREATEST_ASSERT_EQ(b.length, 7U);
	GREATEST_ASSERT_EQ(b.capacity, 10U);

	/* Remove from 4 to the end. */
	buf_erase(&b, 1, -1);
	GREATEST_ASSERT_STR_EQ(b.data, "0");
	GREATEST_ASSERT_EQ(b.length, 1U);
	GREATEST_ASSERT_EQ(b.capacity, 10U);
	buf_finish(&b);

	GREATEST_PASS();
}

GREATEST_TEST
misc_clear(void)
{
	struct buf b = { 0 };

	/* Clear should only reduce the length capacity must not change. */
	buf_puts(&b, "hello world");
	buf_clear(&b);
	GREATEST_ASSERT_STR_EQ(b.data, "");
	GREATEST_ASSERT_EQ(b.length, 0U);
	GREATEST_ASSERT_EQ(b.capacity, 11U);
	buf_finish(&b);

	GREATEST_PASS();
}

GREATEST_SUITE(misc)
{
	GREATEST_RUN_TEST(misc_erase);
	GREATEST_RUN_TEST(misc_clear);
}

GREATEST_MAIN_DEFS();

int
main(int argc, char **argv)
{
	GREATEST_MAIN_BEGIN();
	GREATEST_RUN_SUITE(basics);
	GREATEST_RUN_SUITE(allocs);
	GREATEST_RUN_SUITE(output);
	GREATEST_RUN_SUITE(clones);
	GREATEST_RUN_SUITE(misc);
	GREATEST_MAIN_END();
}