vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

array-test.c

(6863B)


      1 #include <stdlib.h>
      2 #include <stddef.h>
      3 #include <stdbool.h>
      4 #include <string.h>
      5 #include <stdio.h>
      6 #include <errno.h>
      7 #include "tap.h"
      8 #include "array.h"
      9 #include "util.h"
     10 
     11 typedef struct {
     12 	char key[64];
     13 	int value;
     14 } Item;
     15 
     16 static int values[] = { 2, 3, 5, 7, 11 };
     17 static const size_t len = LENGTH(values);
     18 
     19 static bool item_compare(Item *a, Item *b) {
     20 	return strcmp(a->key, b->key) == 0 && a->value == b->value;
     21 }
     22 
     23 static void test_small_objects(void) {
     24 	Array arr;
     25 	array_init_sized(&arr, sizeof(int));
     26 	ok(arr.len == 0, "Initialization");
     27 	ok(!array_set(&arr, 0, NULL) && errno == EINVAL, "Set with invalid index");
     28 	ok(array_get(&arr, 0) == NULL && errno == EINVAL, "Get with invalid index");
     29 	ok(array_peek(&arr) == NULL && arr.len == 0, "Peek empty array");
     30 	ok(array_pop(&arr) == NULL && arr.len == 0, "Pop empty array");
     31 
     32 	for (size_t i = 0; i < len; i++) {
     33 		int *v;
     34 		ok(array_add(&arr, &values[i]) && arr.len == i+1,
     35 			"Add integer: %zu = %d", i, values[i]);
     36 		ok((v = array_get(&arr, i)) && *v == values[i],
     37 			"Get integer: %zu = %d", i, *v);
     38 	}
     39 
     40 	for (size_t i = 0; i < len; i++) {
     41 		ok(array_set(&arr, i, &values[len-i-1]) && arr.len == len,
     42 			"Set array element: %zu = %d", i, values[len-i-1]);
     43 	}
     44 
     45 	for (size_t i = 0; i < len; i++) {
     46 		int *v;
     47 		ok((v = array_get(&arr, i)) && *v == values[len-i-1],
     48 			"Get array element: %zu = %d", i, *v);
     49 	}
     50 
     51 	int *v;
     52 	ok((v = array_peek(&arr)) && *v == values[0] && arr.len == len, "Peek populated array");
     53 	ok((v = array_pop(&arr)) && *v == values[0] && arr.len == len-1, "Pop populated array");
     54 	ok((v = array_peek(&arr)) && *v == values[1] && arr.len == len-1, "Peek after pop");
     55 
     56 	array_clear(&arr);
     57 	ok(arr.len == 0 && array_get(&arr, 0) == NULL && errno == EINVAL, "Clear");
     58 
     59 	for (size_t i = 0; i < len; i++) {
     60 		ok(array_add(&arr, &values[i]) && arr.len == i+1,
     61 			"Re-add integer: %zu = %d", i, values[i]);
     62 	}
     63 
     64 	int old, *tmp;
     65 	ok((tmp = array_get(&arr, 0)) && (old = *tmp) && array_set(&arr, 0, NULL) &&
     66 	    array_get(&arr, 0) == tmp && *tmp == 0 && array_set(&arr, 0, &old) &&
     67 	    array_get(&arr, 0) == tmp && *tmp == old, "Set array element NULL");
     68 	ok(!array_set(&arr, arr.len, &values[0]) && errno == EINVAL, "Get past end of array");
     69 	ok(!array_get(&arr, arr.len) && errno == EINVAL, "Get past end of array");
     70 
     71 	ok(!array_remove(&arr, arr.len) && errno == EINVAL, "Remove past end of array");
     72 
     73 	size_t len_before = arr.len;
     74 	ok(array_remove(&arr, 2) && arr.len == len_before-1 &&
     75 	   (v = array_get(&arr, 0)) && *v == values[0] &&
     76 	   (v = array_get(&arr, 1)) && *v == values[1] &&
     77 	   (v = array_get(&arr, 2)) && *v == values[3] &&
     78 	   (v = array_get(&arr, 3)) && *v == values[4],
     79 	   "Remove element 2");
     80 
     81 	len_before = arr.len;
     82 	ok(array_remove(&arr, 0) && arr.len == len_before-1 &&
     83 	   (v = array_get(&arr, 0)) && *v == values[1] &&
     84 	   (v = array_get(&arr, 1)) && *v == values[3] &&
     85 	   (v = array_get(&arr, 2)) && *v == values[4],
     86 	   "Remove first element");
     87 
     88 	len_before = arr.len;
     89 	ok(array_remove(&arr, len_before-1) && arr.len == len_before-1 &&
     90 	   (v = array_get(&arr, 0)) && *v == values[1] &&
     91 	   (v = array_get(&arr, 1)) && *v == values[3],
     92 	   "Remove last element");
     93 
     94 	array_release(&arr);
     95 }
     96 
     97 static void test_large_objects(void) {
     98 	Array arr;
     99 	array_init_sized(&arr, sizeof(Item));
    100 	ok(arr.len == 0 && array_get(&arr, 0) == NULL && errno == EINVAL,
    101 		"Initialization");
    102 
    103 	Item items[len];
    104 
    105 	for (size_t i = 0; i < len; i++) {
    106 		snprintf(items[i].key, sizeof items[i].key, "key: %zu", i);
    107 		items[i].value = values[i];
    108 		Item *item;
    109 		ok(array_add(&arr, &items[i]) && arr.len == i+1,
    110 			"Add item: %zu = { '%s' = %d }", i, items[i].key, items[i].value);
    111 		ok((item = array_get(&arr, i)) && item != &items[i] && item_compare(item, &items[i]),
    112 			"Get item: %zu = { '%s' = %d }", i, item->key, item->value);
    113 	}
    114 
    115 	for (size_t i = 0; i < len; i++) {
    116 		Item *item = &items[len-i-1];
    117 		ok(array_set(&arr, i, item) && arr.len == len,
    118 			"Set array element: %zu = { '%s' = %d }", i, item->key, item->value);
    119 	}
    120 
    121 	for (size_t i = 0; i < len; i++) {
    122 		Item *item;
    123 		ok((item = array_get(&arr, i)) && item != &items[len-i-1] && item_compare(item, &items[len-i-1]),
    124 			"Get item: %zu = { '%s' = %d }", i, item->key, item->value);
    125 	}
    126 
    127 	ok(!array_add_ptr(&arr, &items[0]) && errno == ENOTSUP && arr.len == len,
    128 		"Adding pointer to non pointer array");
    129 	ok(!array_set_ptr(&arr, 0, &items[0]) && errno == ENOTSUP && item_compare(array_get(&arr, 0), &items[len-1]),
    130 		"Setting pointer in non pointer array");
    131 
    132 	array_clear(&arr);
    133 	ok(arr.len == 0 && array_get(&arr, 0) == NULL && errno == EINVAL, "Clear");
    134 
    135 	array_release(&arr);
    136 }
    137 
    138 static void test_pointers(void) {
    139 
    140 	Array arr;
    141 
    142 	array_init_sized(&arr, 1);
    143 	ok(arr.len == 0 && array_get_ptr(&arr, 0) == NULL && errno == ENOTSUP,
    144 		"Initialization with size 1");
    145 
    146 	ok(!array_add_ptr(&arr, &arr) && errno == ENOTSUP && array_get_ptr(&arr, 0) == NULL,
    147 		"Add pointer to non-pointer array");
    148 
    149 	errno = 0;
    150 	char byte = '_', *ptr;
    151 	ok(array_add(&arr, &byte) && (ptr = array_get(&arr, 0)) && *ptr == byte,
    152 		"Add byte element");
    153 	ok(!array_get_ptr(&arr, 0) && errno == ENOTSUP, "Get pointer from non-pointer array");
    154 	array_release(&arr);
    155 
    156 	array_init(&arr);
    157 	ok(arr.len == 0 && array_get_ptr(&arr, 0) == NULL && errno == EINVAL,
    158 		"Initialization");
    159 
    160 	Item *items[len];
    161 
    162 	for (size_t i = 0; i < len; i++) {
    163 		items[i] = malloc(sizeof(Item));
    164 		snprintf(items[i]->key, sizeof(items[i]->key), "key: %zu", i);
    165 		items[i]->value = values[i];
    166 	}
    167 
    168 	for (size_t i = 0; i < len; i++) {
    169 		Item *item;
    170 		ok(array_add_ptr(&arr, items[i]) && arr.len == i+1,
    171 			"Add item: %zu = %p", i, (void*)items[i]);
    172 		ok((item = array_get_ptr(&arr, i)) && item == items[i],
    173 			"Get item: %zu = %p", i, (void*)item);
    174 	}
    175 
    176 	for (size_t i = 0; i < len; i++) {
    177 		Item *item = items[len-i-1];
    178 		ok(array_set_ptr(&arr, i, item) && arr.len == len,
    179 			"Set item: %zu = %p", i, (void*)item);
    180 	}
    181 
    182 	for (size_t i = 0; i < len; i++) {
    183 		Item *item;
    184 		ok((item = array_get_ptr(&arr, i)) && item == items[len-i-1],
    185 			"Get item: %zu = %p", i, (void*)item);
    186 	}
    187 
    188 	Item *tmp;
    189 	ok((tmp = array_get_ptr(&arr, 0)) && array_set_ptr(&arr, 0, NULL) &&
    190 	    array_get_ptr(&arr, 0) == NULL && array_set_ptr(&arr, 0, tmp) &&
    191 	    array_get_ptr(&arr, 0) == tmp, "Set pointer NULL");
    192 	ok(!array_set_ptr(&arr, arr.len, items[0]) && errno == EINVAL, "Set pointer past end of array");
    193 	ok(!array_get_ptr(&arr, arr.len) && errno == EINVAL, "Get pointer past end of array");
    194 
    195 	array_clear(&arr);
    196 	ok(arr.len == 0 && array_get_ptr(&arr, 0) == NULL && errno == EINVAL, "Clear");
    197 
    198 	for (size_t i = 0; i < len; i++) {
    199 		ok(array_add_ptr(&arr, items[i]) && arr.len == i+1,
    200 			"Re-add item: %zu = %p", i, (void*)items[i]);
    201 	}
    202 	array_release_full(&arr);
    203 }
    204 
    205 int main(int argc, char *argv[]) {
    206 	plan_no_plan();
    207 
    208 	test_small_objects();
    209 	test_large_objects();
    210 	test_pointers();
    211 
    212 	return exit_status();
    213 }