1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/* -*- coding: utf-8 -*-
* ----------------------------------------------------------------------
* Copyright © 2009-2014, RedJack, LLC.
* All rights reserved.
*
* Please see the COPYING file in this distribution for license details.
* ----------------------------------------------------------------------
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <check.h>
#include "libcork/ds/slice.h"
#include "helpers.h"
/*-----------------------------------------------------------------------
* Static slices
*/
START_TEST(test_static_slice)
{
static char SRC[] = "Here is some text.";
size_t SRC_LEN = sizeof(SRC) - 1;
struct cork_slice slice;
struct cork_slice copy1;
struct cork_slice lcopy1;
cork_slice_init_static(&slice, SRC, SRC_LEN);
fail_if_error(cork_slice_copy(©1, &slice, 8, 4));
fail_if_error(cork_slice_light_copy(&lcopy1, &slice, 8, 4));
fail_if_error(cork_slice_slice(&slice, 8, 4));
fail_unless(cork_slice_equal(&slice, ©1), "Slices should be equal");
fail_unless(cork_slice_equal(&slice, &lcopy1), "Slices should be equal");
/* We have to finish lcopy1 first, since it's a light copy. */
cork_slice_finish(&lcopy1);
cork_slice_finish(&slice);
cork_slice_finish(©1);
}
END_TEST
/*-----------------------------------------------------------------------
* Copy-once slices
*/
START_TEST(test_copy_once_slice)
{
static char SRC[] = "Here is some text.";
size_t SRC_LEN = sizeof(SRC) - 1;
struct cork_slice slice;
struct cork_slice copy1;
struct cork_slice copy2;
struct cork_slice lcopy1;
struct cork_slice lcopy2;
cork_slice_init_copy_once(&slice, SRC, SRC_LEN);
fail_unless(slice.buf == SRC, "Unexpected slice buffer");
fail_if_error(cork_slice_light_copy(&lcopy1, &slice, 8, 4));
/* We should still be using the original SRC buffer directly, since we only
* created a light copy. */
fail_unless(slice.buf == SRC, "Unexpected slice buffer");
fail_unless(slice.buf + 8 == lcopy1.buf, "Unexpected slice buffer");
fail_if_error(cork_slice_copy(©1, &slice, 8, 4));
fail_if_error(cork_slice_slice(&slice, 8, 4));
/* Once we create a full copy, the content should have been moved into a
* managed buffer, which will exist somewhere else in memory than the
* original SRC pointer. */
fail_unless(slice.buf != SRC, "Unexpected slice buffer");
fail_unless(slice.buf == copy1.buf, "Unexpected slice buffer");
/* The light copy that we made previously won't have been moved over to the
* new managed buffer, though. */
fail_unless(cork_slice_equal(&slice, ©1), "Slices should be equal");
/* Once we've switched over to the managed buffer, a new light copy should
* still point into the managed buffer. */
fail_if_error(cork_slice_light_copy(&lcopy2, &slice, 0, 4));
fail_unless(slice.buf != SRC, "Unexpected slice buffer");
fail_unless(slice.buf == lcopy2.buf, "Unexpected slice buffer");
fail_if_error(cork_slice_copy(©2, &slice, 0, 4));
/* The second full copy should not create a new managed buffer, it should
* just increment the existing managed buffer's refcount. */
fail_unless(slice.buf == copy2.buf, "Unexpected slice buffer");
fail_unless(copy1.buf == copy2.buf, "Unexpected slice buffer");
fail_unless(cork_slice_equal(&slice, ©2), "Slices should be equal");
fail_unless(cork_slice_equal(©1, ©2), "Slices should be equal");
/* We have to finish the light copies first. */
cork_slice_finish(&lcopy1);
cork_slice_finish(&lcopy2);
cork_slice_finish(&slice);
cork_slice_finish(©1);
cork_slice_finish(©2);
}
END_TEST
/*-----------------------------------------------------------------------
* Testing harness
*/
Suite *
test_suite()
{
Suite *s = suite_create("slice");
TCase *tc_slice = tcase_create("slice");
tcase_add_test(tc_slice, test_static_slice);
tcase_add_test(tc_slice, test_copy_once_slice);
suite_add_tcase(s, tc_slice);
return s;
}
int
main(int argc, const char **argv)
{
int number_failed;
Suite *suite = test_suite();
SRunner *runner = srunner_create(suite);
setup_allocator();
srunner_run_all(runner, CK_NORMAL);
number_failed = srunner_ntests_failed(runner);
srunner_free(runner);
return (number_failed == 0)? EXIT_SUCCESS: EXIT_FAILURE;
}
|