list.cpp 3.86 KB
Newer Older
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
/** Unit tests for array-based list
 *
 * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
 * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC
 * @license GNU General Public License (version 3)
 *
 * VILLAScommon
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *********************************************************************************/

#include <stdint.h>
#include <string.h>
#include <criterion/criterion.h>

#include <villas/utils.h>
#include <villas/list.h>

Steffen Vogel's avatar
Steffen Vogel committed
30
static const char *nouns[] = { "time", "person", "year", "way", "day", "thing", "man", "world", "life", "hand", "part", "child", "eye", "woman", "place", "work", "week", "case", "point", "government", "company", "number", "group", "problem", "fact" };
31
32

struct data {
Steffen Vogel's avatar
Steffen Vogel committed
33
	const char *tag;
34
35
36
	int data;
};

37
TestSuite(list, .description = "List datastructure");
Steffen Vogel's avatar
Steffen Vogel committed
38

39
40
Test(list, list_lookup)
{
Steffen Vogel's avatar
Steffen Vogel committed
41
42
	struct list l;
	l.state = STATE_DESTROYED;
43
44
45

	list_init(&l);

Steffen Vogel's avatar
Steffen Vogel committed
46
47
	for (unsigned i = 0; i < ARRAY_LEN(nouns); i++) {
		struct data *d = new struct data;
48
49
50
51
52
53
54

		d->tag = nouns[i];
		d->data = i;

		list_push(&l, d);
	}

Steffen Vogel's avatar
Steffen Vogel committed
55
	struct data *found = (struct data *) list_lookup(&l, "woman");
56
57
58

	cr_assert_eq(found->data, 13);

Steffen Vogel's avatar
Steffen Vogel committed
59
	list_destroy(&l, nullptr, true);
60
61
62
63
}

Test(list, list_search)
{
Steffen Vogel's avatar
Steffen Vogel committed
64
65
	struct list l;
	l.state = STATE_DESTROYED;
66
67
68
69

	list_init(&l);

	/* Fill list */
Steffen Vogel's avatar
Steffen Vogel committed
70
71
	for (unsigned i = 0; i < ARRAY_LEN(nouns); i++)
		list_push(&l, (void *) nouns[i]);
72
73
74
75
76
77
78

	cr_assert_eq(list_length(&l), ARRAY_LEN(nouns));

	/* Declare on stack! */
	char positive[] = "woman";
	char negative[] = "dinosaurrier";

Steffen Vogel's avatar
Steffen Vogel committed
79
	char *found = (char *) list_search(&l, (cmp_cb_t) strcmp, positive);
80
81
82
83
84
85
86
	cr_assert_not_null(found);
	cr_assert_eq(found, nouns[13], "found = %p, nouns[13] = %p", found, nouns[13]);
	cr_assert_str_eq(found, positive);

	char *not_found = (char *) list_search(&l, (cmp_cb_t) strcmp, negative);
	cr_assert_null(not_found);

Steffen Vogel's avatar
Steffen Vogel committed
87
	list_destroy(&l, nullptr, false);
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
}

struct content {
	int destroyed;
};

static int dtor(void *ptr)
{
	struct content *elm = (struct content *) ptr;

	elm->destroyed = 1;

	return 0;
}

Test(list, destructor)
{
Steffen Vogel's avatar
Steffen Vogel committed
105
106
107
108
109
	struct list l;
	l.state = STATE_DESTROYED;

	struct content elm;
	elm.destroyed = 0;
110
111
112
113
114
115
116
117
118
119
120
121

	list_init(&l);
	list_push(&l, &elm);

	cr_assert_eq(list_length(&l), 1);

	list_destroy(&l, dtor, false);

	cr_assert_eq(elm.destroyed, 1);
}

static int compare(const void *a, const void *b) {
Steffen Vogel's avatar
Steffen Vogel committed
122
	return (intptr_t) b - (intptr_t) a;
123
124
125
126
127
128
}

Test(list, basics)
{
	intptr_t i;
	int ret;
Steffen Vogel's avatar
Steffen Vogel committed
129
130
	struct list l;
	l.state = STATE_DESTROYED;
131
132
133
134
135
136
137
138
139

	list_init(&l);

	for (i = 0; i < 100; i++) {
		cr_assert_eq(list_length(&l), i);

		list_push(&l, (void *) i);
	}

Steffen Vogel's avatar
Steffen Vogel committed
140
	cr_assert_eq(list_at_safe(&l, 555), nullptr);
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
	cr_assert_eq(list_last(&l), (void *) 99);
	cr_assert_eq(list_first(&l), (void *) 0);

	for (size_t j = 0, i = 0; j < list_length(&l); j++) {
		void *k = list_at(&l, j);

		cr_assert_eq(k, (void *) i++);
	}

	list_sort(&l, compare); /* Reverse list */

	for (size_t j = 0, i = 99; j < list_length(&l); j++) {
		void *k = list_at(&l, j);

		cr_assert_eq(k, (void *) i, "Is %#zx, expected %p", i, k);
		i--;
	}

	ret = list_contains(&l, (void *) 55);
	cr_assert(ret);

	list_remove(&l, (void *) 55);

	ret = list_contains(&l, (void *) 55);
	cr_assert(!ret);

Steffen Vogel's avatar
Steffen Vogel committed
167
	list_destroy(&l, nullptr, false);
168
169
170
171

	ret = list_length(&l);
	cr_assert_eq(ret, -1, "List not properly destroyed: l.length = %zd", l.length);
}