1/*	$NetBSD$	*/
2
3/*
4 * Automated Testing Framework (atf)
5 *
6 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
19 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <stdio.h>
33#include <string.h>
34
35#include <atf-c.h>
36
37#include "atf-c/utils.h"
38
39#include "list.h"
40#include "test_helpers.h"
41
42/* ---------------------------------------------------------------------
43 * Tests for the "atf_list" type.
44 * --------------------------------------------------------------------- */
45
46/*
47 * Constructors and destructors.
48 */
49
50ATF_TC(list_init);
51ATF_TC_HEAD(list_init, tc)
52{
53    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_init function");
54}
55ATF_TC_BODY(list_init, tc)
56{
57    atf_list_t list;
58
59    RE(atf_list_init(&list));
60    ATF_REQUIRE_EQ(atf_list_size(&list), 0);
61    atf_list_fini(&list);
62}
63
64/*
65 * Getters.
66 */
67
68ATF_TC(list_index);
69ATF_TC_HEAD(list_index, tc)
70{
71    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_index function");
72}
73ATF_TC_BODY(list_index, tc)
74{
75    atf_list_t list;
76    int i1 = 1;
77    int i2 = 5;
78    int i3 = 9;
79
80    RE(atf_list_init(&list));
81    RE(atf_list_append(&list, &i1, false));
82    RE(atf_list_append(&list, &i2, false));
83    RE(atf_list_append(&list, &i3, false));
84
85    ATF_CHECK_EQ(*(int *)atf_list_index(&list, 0), 1);
86    ATF_CHECK_EQ(*(int *)atf_list_index(&list, 1), 5);
87    ATF_CHECK_EQ(*(int *)atf_list_index(&list, 2), 9);
88
89    atf_list_fini(&list);
90}
91
92ATF_TC(list_index_c);
93ATF_TC_HEAD(list_index_c, tc)
94{
95    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_index_c function");
96}
97ATF_TC_BODY(list_index_c, tc)
98{
99    atf_list_t list;
100    int i1 = 1;
101    int i2 = 5;
102    int i3 = 9;
103
104    RE(atf_list_init(&list));
105    RE(atf_list_append(&list, &i1, false));
106    RE(atf_list_append(&list, &i2, false));
107    RE(atf_list_append(&list, &i3, false));
108
109    ATF_CHECK_EQ(*(const int *)atf_list_index_c(&list, 0), 1);
110    ATF_CHECK_EQ(*(const int *)atf_list_index_c(&list, 1), 5);
111    ATF_CHECK_EQ(*(const int *)atf_list_index_c(&list, 2), 9);
112
113    atf_list_fini(&list);
114}
115
116ATF_TC_WITHOUT_HEAD(list_to_charpp_empty);
117ATF_TC_BODY(list_to_charpp_empty, tc)
118{
119    atf_list_t list;
120    char **array;
121
122    RE(atf_list_init(&list));
123    ATF_REQUIRE((array = atf_list_to_charpp(&list)) != NULL);
124    atf_list_fini(&list);
125
126    ATF_CHECK_EQ(NULL, array[0]);
127    atf_utils_free_charpp(array);
128}
129
130ATF_TC_WITHOUT_HEAD(list_to_charpp_some);
131ATF_TC_BODY(list_to_charpp_some, tc)
132{
133    atf_list_t list;
134    char **array;
135
136    char s1[] = "one";
137    char s2[] = "two";
138    char s3[] = "three";
139
140    RE(atf_list_init(&list));
141    RE(atf_list_append(&list, s1, false));
142    RE(atf_list_append(&list, s2, false));
143    RE(atf_list_append(&list, s3, false));
144    ATF_REQUIRE((array = atf_list_to_charpp(&list)) != NULL);
145    atf_list_fini(&list);
146
147    ATF_CHECK_STREQ("one", array[0]);
148    ATF_CHECK_STREQ("two", array[1]);
149    ATF_CHECK_STREQ("three", array[2]);
150    ATF_CHECK_EQ(NULL, array[3]);
151    atf_utils_free_charpp(array);
152}
153
154/*
155 * Modifiers.
156 */
157
158ATF_TC(list_append);
159ATF_TC_HEAD(list_append, tc)
160{
161    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_append function");
162}
163ATF_TC_BODY(list_append, tc)
164{
165    atf_list_t list;
166    size_t i;
167    char buf[] = "Test string";
168
169    RE(atf_list_init(&list));
170    for (i = 0; i < 1024; i++) {
171        ATF_REQUIRE_EQ(atf_list_size(&list), i);
172        RE(atf_list_append(&list, buf, false));
173    }
174    atf_list_fini(&list);
175}
176
177ATF_TC(list_append_list);
178ATF_TC_HEAD(list_append_list, tc)
179{
180    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_append_list "
181                      "function");
182}
183ATF_TC_BODY(list_append_list, tc)
184{
185    {
186        atf_list_t l1, l2;
187
188        RE(atf_list_init(&l1));
189        RE(atf_list_init(&l2));
190
191        atf_list_append_list(&l1, &l2);
192        ATF_CHECK_EQ(atf_list_size(&l1), 0);
193
194        atf_list_fini(&l1);
195    }
196
197    {
198        atf_list_t l1, l2;
199        int item = 5;
200
201        RE(atf_list_init(&l1));
202        RE(atf_list_append(&l1, &item, false));
203        RE(atf_list_init(&l2));
204
205        atf_list_append_list(&l1, &l2);
206        ATF_CHECK_EQ(atf_list_size(&l1), 1);
207        ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 0), item);
208
209        atf_list_fini(&l1);
210    }
211
212    {
213        atf_list_t l1, l2;
214        int item = 5;
215
216        RE(atf_list_init(&l1));
217        RE(atf_list_init(&l2));
218        RE(atf_list_append(&l2, &item, false));
219
220        atf_list_append_list(&l1, &l2);
221        ATF_CHECK_EQ(atf_list_size(&l1), 1);
222        ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 0), item);
223
224        atf_list_fini(&l1);
225    }
226
227    {
228        atf_list_t l1, l2;
229        int item1 = 5;
230        int item2 = 9;
231
232        RE(atf_list_init(&l1));
233        RE(atf_list_append(&l1, &item1, false));
234        RE(atf_list_init(&l2));
235        RE(atf_list_append(&l2, &item2, false));
236
237        atf_list_append_list(&l1, &l2);
238        ATF_CHECK_EQ(atf_list_size(&l1), 2);
239        ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 0), item1);
240        ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 1), item2);
241
242        atf_list_fini(&l1);
243    }
244
245    {
246        atf_list_t l1, l2;
247        atf_list_citer_t end1, end2;
248
249        RE(atf_list_init(&l1));
250        RE(atf_list_init(&l2));
251
252        end1 = atf_list_end_c(&l1);
253        end2 = atf_list_end_c(&l2);
254        /* XXX Shouldn't query m_entry here. */
255        ATF_CHECK(end1.m_entry != end2.m_entry);
256
257        atf_list_append_list(&l1, &l2);
258        ATF_CHECK(atf_list_end_c(&l1).m_entry == end2.m_entry);
259
260        atf_list_fini(&l1);
261    }
262}
263
264/*
265 * Macros.
266 */
267
268ATF_TC(list_for_each);
269ATF_TC_HEAD(list_for_each, tc)
270{
271    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_for_each macro");
272}
273ATF_TC_BODY(list_for_each, tc)
274{
275    atf_list_t list;
276    atf_list_iter_t iter;
277    size_t count, i, size;
278    int nums[10];
279
280    printf("Iterating over empty list\n");
281    RE(atf_list_init(&list));
282    count = 0;
283    atf_list_for_each(iter, &list) {
284        count++;
285        printf("Item count is now %zd\n", count);
286    }
287    ATF_REQUIRE_EQ(count, 0);
288    atf_list_fini(&list);
289
290    for (size = 0; size <= 10; size++) {
291        printf("Iterating over list of %zd elements\n", size);
292        RE(atf_list_init(&list));
293        for (i = 0; i < size; i++) {
294            nums[i] = i + 1;
295            RE(atf_list_append(&list, &nums[i], false));
296        }
297        count = 0;
298        atf_list_for_each(iter, &list) {
299            printf("Retrieved item: %d\n", *(int *)atf_list_iter_data(iter));
300            count++;
301        }
302        ATF_REQUIRE_EQ(count, size);
303        atf_list_fini(&list);
304    }
305}
306
307ATF_TC(list_for_each_c);
308ATF_TC_HEAD(list_for_each_c, tc)
309{
310    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_for_each_c macro");
311}
312ATF_TC_BODY(list_for_each_c, tc)
313{
314    atf_list_t list;
315    atf_list_citer_t iter;
316    size_t count, i, size;
317    int nums[10];
318
319    printf("Iterating over empty list\n");
320    RE(atf_list_init(&list));
321    count = 0;
322    atf_list_for_each_c(iter, &list) {
323        count++;
324        printf("Item count is now %zd\n", count);
325    }
326    ATF_REQUIRE_EQ(count, 0);
327    atf_list_fini(&list);
328
329    for (size = 0; size <= 10; size++) {
330        printf("Iterating over list of %zd elements\n", size);
331        RE(atf_list_init(&list));
332        for (i = 0; i < size; i++) {
333            nums[i] = i + 1;
334            RE(atf_list_append(&list, &nums[i], false));
335        }
336        count = 0;
337        atf_list_for_each_c(iter, &list) {
338            printf("Retrieved item: %d\n",
339                   *(const int *)atf_list_citer_data(iter));
340            count++;
341        }
342        ATF_REQUIRE_EQ(count, size);
343        atf_list_fini(&list);
344    }
345}
346
347/* ---------------------------------------------------------------------
348 * Main.
349 * --------------------------------------------------------------------- */
350
351ATF_TP_ADD_TCS(tp)
352{
353    /* Constructors and destructors. */
354    ATF_TP_ADD_TC(tp, list_init);
355
356    /* Getters. */
357    ATF_TP_ADD_TC(tp, list_index);
358    ATF_TP_ADD_TC(tp, list_index_c);
359    ATF_TP_ADD_TC(tp, list_to_charpp_empty);
360    ATF_TP_ADD_TC(tp, list_to_charpp_some);
361
362    /* Modifiers. */
363    ATF_TP_ADD_TC(tp, list_append);
364    ATF_TP_ADD_TC(tp, list_append_list);
365
366    /* Macros. */
367    ATF_TP_ADD_TC(tp, list_for_each);
368    ATF_TP_ADD_TC(tp, list_for_each_c);
369
370    return atf_no_error();
371}
372