1240116Smarcel/*
2240116Smarcel * Automated Testing Framework (atf)
3240116Smarcel *
4240116Smarcel * Copyright (c) 2008 The NetBSD Foundation, Inc.
5240116Smarcel * All rights reserved.
6240116Smarcel *
7240116Smarcel * Redistribution and use in source and binary forms, with or without
8240116Smarcel * modification, are permitted provided that the following conditions
9240116Smarcel * are met:
10240116Smarcel * 1. Redistributions of source code must retain the above copyright
11240116Smarcel *    notice, this list of conditions and the following disclaimer.
12240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright
13240116Smarcel *    notice, this list of conditions and the following disclaimer in the
14240116Smarcel *    documentation and/or other materials provided with the distribution.
15240116Smarcel *
16240116Smarcel * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17240116Smarcel * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18240116Smarcel * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19240116Smarcel * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20240116Smarcel * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21240116Smarcel * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22240116Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23240116Smarcel * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24240116Smarcel * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25240116Smarcel * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26240116Smarcel * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27240116Smarcel * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28240116Smarcel */
29240116Smarcel
30240116Smarcel#include <stdio.h>
31240116Smarcel#include <stdlib.h>
32240116Smarcel#include <string.h>
33240116Smarcel
34240116Smarcel#include <atf-c.h>
35240116Smarcel
36240116Smarcel#include "sanity.h"
37240116Smarcel#include "test_helpers.h"
38240116Smarcel#include "text.h"
39240116Smarcel
40240116Smarcel/* ---------------------------------------------------------------------
41240116Smarcel * Auxiliary functions.
42240116Smarcel * --------------------------------------------------------------------- */
43240116Smarcel
44240116Smarcel#define REQUIRE_ERROR(exp) \
45240116Smarcel    do { \
46240116Smarcel        atf_error_t err = exp; \
47240116Smarcel        ATF_REQUIRE(atf_is_error(err)); \
48240116Smarcel        atf_error_free(err); \
49240116Smarcel    } while (0)
50240116Smarcel
51240116Smarcelstatic
52240116Smarcelsize_t
53240116Smarcelarray_size(const char *words[])
54240116Smarcel{
55240116Smarcel    size_t count;
56240116Smarcel    const char **word;
57240116Smarcel
58240116Smarcel    count = 0;
59240116Smarcel    for (word = words; *word != NULL; word++)
60240116Smarcel        count++;
61240116Smarcel
62240116Smarcel    return count;
63240116Smarcel}
64240116Smarcel
65240116Smarcelstatic
66240116Smarcelvoid
67240116Smarcelcheck_split(const char *str, const char *delim, const char *words[])
68240116Smarcel{
69240116Smarcel    atf_list_t list;
70240116Smarcel    const char **word;
71240116Smarcel    size_t i;
72240116Smarcel
73240116Smarcel    printf("Splitting '%s' with delimiter '%s'\n", str, delim);
74240116Smarcel    CE(atf_text_split(str, delim, &list));
75240116Smarcel
76240116Smarcel    printf("Expecting %zd words\n", array_size(words));
77240116Smarcel    ATF_CHECK_EQ(atf_list_size(&list), array_size(words));
78240116Smarcel
79240116Smarcel    for (word = words, i = 0; *word != NULL; word++, i++) {
80240116Smarcel        printf("Word at position %zd should be '%s'\n", i, words[i]);
81240116Smarcel        ATF_CHECK_STREQ((const char *)atf_list_index_c(&list, i), words[i]);
82240116Smarcel    }
83240116Smarcel
84240116Smarcel    atf_list_fini(&list);
85240116Smarcel}
86240116Smarcel
87240116Smarcelstatic
88240116Smarcelatf_error_t
89240116Smarcelword_acum(const char *word, void *data)
90240116Smarcel{
91240116Smarcel    char *acum = data;
92240116Smarcel
93240116Smarcel    strcat(acum, word);
94240116Smarcel
95240116Smarcel    return atf_no_error();
96240116Smarcel}
97240116Smarcel
98240116Smarcelstatic
99240116Smarcelatf_error_t
100240116Smarcelword_count(const char *word ATF_DEFS_ATTRIBUTE_UNUSED, void *data)
101240116Smarcel{
102240116Smarcel    size_t *counter = data;
103240116Smarcel
104240116Smarcel    (*counter)++;
105240116Smarcel
106240116Smarcel    return atf_no_error();
107240116Smarcel}
108240116Smarcel
109240116Smarcelstruct fail_at {
110240116Smarcel    int failpos;
111240116Smarcel    int curpos;
112240116Smarcel};
113240116Smarcel
114240116Smarcelstatic
115240116Smarcelatf_error_t
116240116Smarcelword_fail_at(const char *word ATF_DEFS_ATTRIBUTE_UNUSED, void *data)
117240116Smarcel{
118240116Smarcel    struct fail_at *fa = data;
119240116Smarcel    atf_error_t err;
120240116Smarcel
121240116Smarcel    if (fa->failpos == fa->curpos)
122240116Smarcel        err = atf_no_memory_error(); /* Just a random error. */
123240116Smarcel    else {
124240116Smarcel        fa->curpos++;
125240116Smarcel        err = atf_no_error();
126240116Smarcel    }
127240116Smarcel
128240116Smarcel    return err;
129240116Smarcel}
130240116Smarcel
131240116Smarcel/* ---------------------------------------------------------------------
132240116Smarcel * Test cases for the free functions.
133240116Smarcel * --------------------------------------------------------------------- */
134240116Smarcel
135240116SmarcelATF_TC(for_each_word);
136240116SmarcelATF_TC_HEAD(for_each_word, tc)
137240116Smarcel{
138240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks the atf_text_for_each_word"
139240116Smarcel                      "function");
140240116Smarcel}
141240116SmarcelATF_TC_BODY(for_each_word, tc)
142240116Smarcel{
143240116Smarcel    size_t cnt;
144240116Smarcel    char acum[1024];
145240116Smarcel
146240116Smarcel    cnt = 0;
147240116Smarcel    strcpy(acum, "");
148240116Smarcel    RE(atf_text_for_each_word("1 2 3", " ", word_count, &cnt));
149240116Smarcel    RE(atf_text_for_each_word("1 2 3", " ", word_acum, acum));
150240116Smarcel    ATF_REQUIRE(cnt == 3);
151240116Smarcel    ATF_REQUIRE(strcmp(acum, "123") == 0);
152240116Smarcel
153240116Smarcel    cnt = 0;
154240116Smarcel    strcpy(acum, "");
155240116Smarcel    RE(atf_text_for_each_word("1 2 3", ".", word_count, &cnt));
156240116Smarcel    RE(atf_text_for_each_word("1 2 3", ".", word_acum, acum));
157240116Smarcel    ATF_REQUIRE(cnt == 1);
158240116Smarcel    ATF_REQUIRE(strcmp(acum, "1 2 3") == 0);
159240116Smarcel
160240116Smarcel    cnt = 0;
161240116Smarcel    strcpy(acum, "");
162240116Smarcel    RE(atf_text_for_each_word("1 2 3 4 5", " ", word_count, &cnt));
163240116Smarcel    RE(atf_text_for_each_word("1 2 3 4 5", " ", word_acum, acum));
164240116Smarcel    ATF_REQUIRE(cnt == 5);
165240116Smarcel    ATF_REQUIRE(strcmp(acum, "12345") == 0);
166240116Smarcel
167240116Smarcel    cnt = 0;
168240116Smarcel    strcpy(acum, "");
169240116Smarcel    RE(atf_text_for_each_word("1 2.3.4 5", " .", word_count, &cnt));
170240116Smarcel    RE(atf_text_for_each_word("1 2.3.4 5", " .", word_acum, acum));
171240116Smarcel    ATF_REQUIRE(cnt == 5);
172240116Smarcel    ATF_REQUIRE(strcmp(acum, "12345") == 0);
173240116Smarcel
174240116Smarcel    {
175240116Smarcel        struct fail_at fa;
176240116Smarcel        fa.failpos = 3;
177240116Smarcel        fa.curpos = 0;
178240116Smarcel        atf_error_t err = atf_text_for_each_word("a b c d e", " ",
179240116Smarcel                                                 word_fail_at, &fa);
180240116Smarcel        ATF_REQUIRE(atf_is_error(err));
181240116Smarcel        ATF_REQUIRE(atf_error_is(err, "no_memory"));
182240116Smarcel        ATF_REQUIRE(fa.curpos == 3);
183240116Smarcel        atf_error_free(err);
184240116Smarcel    }
185240116Smarcel}
186240116Smarcel
187240116SmarcelATF_TC(format);
188240116SmarcelATF_TC_HEAD(format, tc)
189240116Smarcel{
190240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form "
191240116Smarcel                      "strings using a variable parameters list");
192240116Smarcel}
193240116SmarcelATF_TC_BODY(format, tc)
194240116Smarcel{
195240116Smarcel    char *str;
196240116Smarcel    atf_error_t err;
197240116Smarcel
198240116Smarcel    err = atf_text_format(&str, "%s %s %d", "Test", "string", 1);
199240116Smarcel    ATF_REQUIRE(!atf_is_error(err));
200240116Smarcel    ATF_REQUIRE(strcmp(str, "Test string 1") == 0);
201240116Smarcel    free(str);
202240116Smarcel}
203240116Smarcel
204240116Smarcelstatic
205240116Smarcelvoid
206240116Smarcelformat_ap(char **dest, const char *fmt, ...)
207240116Smarcel{
208240116Smarcel    va_list ap;
209240116Smarcel    atf_error_t err;
210240116Smarcel
211240116Smarcel    va_start(ap, fmt);
212240116Smarcel    err = atf_text_format_ap(dest, fmt, ap);
213240116Smarcel    va_end(ap);
214240116Smarcel
215240116Smarcel    ATF_REQUIRE(!atf_is_error(err));
216240116Smarcel}
217240116Smarcel
218240116SmarcelATF_TC(format_ap);
219240116SmarcelATF_TC_HEAD(format_ap, tc)
220240116Smarcel{
221240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form "
222240116Smarcel                      "strings using a va_list argument");
223240116Smarcel}
224240116SmarcelATF_TC_BODY(format_ap, tc)
225240116Smarcel{
226240116Smarcel    char *str;
227240116Smarcel
228240116Smarcel    format_ap(&str, "%s %s %d", "Test", "string", 1);
229240116Smarcel    ATF_REQUIRE(strcmp(str, "Test string 1") == 0);
230240116Smarcel    free(str);
231240116Smarcel}
232240116Smarcel
233240116SmarcelATF_TC(split);
234240116SmarcelATF_TC_HEAD(split, tc)
235240116Smarcel{
236240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks the split function");
237240116Smarcel}
238240116SmarcelATF_TC_BODY(split, tc)
239240116Smarcel{
240240116Smarcel    {
241240116Smarcel        const char *words[] = { NULL };
242240116Smarcel        check_split("", " ", words);
243240116Smarcel    }
244240116Smarcel
245240116Smarcel    {
246240116Smarcel        const char *words[] = { NULL };
247240116Smarcel        check_split(" ", " ", words);
248240116Smarcel    }
249240116Smarcel
250240116Smarcel    {
251240116Smarcel        const char *words[] = { NULL };
252240116Smarcel        check_split("    ", " ", words);
253240116Smarcel    }
254240116Smarcel
255240116Smarcel    {
256240116Smarcel        const char *words[] = { "a", "b", NULL };
257240116Smarcel        check_split("a b", " ", words);
258240116Smarcel    }
259240116Smarcel
260240116Smarcel    {
261240116Smarcel        const char *words[] = { "a", "b", "c", "d", NULL };
262240116Smarcel        check_split("a b c d", " ", words);
263240116Smarcel    }
264240116Smarcel
265240116Smarcel    {
266240116Smarcel        const char *words[] = { "foo", "bar", NULL };
267240116Smarcel        check_split("foo bar", " ", words);
268240116Smarcel    }
269240116Smarcel
270240116Smarcel    {
271240116Smarcel        const char *words[] = { "foo", "bar", "baz", "foobar", NULL };
272240116Smarcel        check_split("foo bar baz foobar", " ", words);
273240116Smarcel    }
274240116Smarcel
275240116Smarcel    {
276240116Smarcel        const char *words[] = { "foo", "bar", NULL };
277240116Smarcel        check_split(" foo bar", " ", words);
278240116Smarcel    }
279240116Smarcel
280240116Smarcel    {
281240116Smarcel        const char *words[] = { "foo", "bar", NULL };
282240116Smarcel        check_split("foo  bar", " ", words);
283240116Smarcel    }
284240116Smarcel
285240116Smarcel    {
286240116Smarcel        const char *words[] = { "foo", "bar", NULL };
287240116Smarcel        check_split("foo bar ", " ", words);
288240116Smarcel    }
289240116Smarcel
290240116Smarcel    {
291240116Smarcel        const char *words[] = { "foo", "bar", NULL };
292240116Smarcel        check_split("  foo  bar  ", " ", words);
293240116Smarcel    }
294240116Smarcel}
295240116Smarcel
296240116SmarcelATF_TC(split_delims);
297240116SmarcelATF_TC_HEAD(split_delims, tc)
298240116Smarcel{
299240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks the split function using "
300240116Smarcel                      "different delimiters");
301240116Smarcel}
302240116SmarcelATF_TC_BODY(split_delims, tc)
303240116Smarcel{
304240116Smarcel
305240116Smarcel    {
306240116Smarcel        const char *words[] = { NULL };
307240116Smarcel        check_split("", "/", words);
308240116Smarcel    }
309240116Smarcel
310240116Smarcel    {
311240116Smarcel        const char *words[] = { " ", NULL };
312240116Smarcel        check_split(" ", "/", words);
313240116Smarcel    }
314240116Smarcel
315240116Smarcel    {
316240116Smarcel        const char *words[] = { "    ", NULL };
317240116Smarcel        check_split("    ", "/", words);
318240116Smarcel    }
319240116Smarcel
320240116Smarcel    {
321240116Smarcel        const char *words[] = { "a", "b", NULL };
322240116Smarcel        check_split("a/b", "/", words);
323240116Smarcel    }
324240116Smarcel
325240116Smarcel    {
326240116Smarcel        const char *words[] = { "a", "bcd", "ef", NULL };
327240116Smarcel        check_split("aLONGDELIMbcdLONGDELIMef", "LONGDELIM", words);
328240116Smarcel    }
329240116Smarcel}
330240116Smarcel
331240116SmarcelATF_TC(to_bool);
332240116SmarcelATF_TC_HEAD(to_bool, tc)
333240116Smarcel{
334240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_bool function");
335240116Smarcel}
336240116SmarcelATF_TC_BODY(to_bool, tc)
337240116Smarcel{
338240116Smarcel    bool b;
339240116Smarcel
340240116Smarcel    RE(atf_text_to_bool("true", &b)); ATF_REQUIRE(b);
341240116Smarcel    RE(atf_text_to_bool("TRUE", &b)); ATF_REQUIRE(b);
342240116Smarcel    RE(atf_text_to_bool("yes", &b)); ATF_REQUIRE(b);
343240116Smarcel    RE(atf_text_to_bool("YES", &b)); ATF_REQUIRE(b);
344240116Smarcel
345240116Smarcel    RE(atf_text_to_bool("false", &b)); ATF_REQUIRE(!b);
346240116Smarcel    RE(atf_text_to_bool("FALSE", &b)); ATF_REQUIRE(!b);
347240116Smarcel    RE(atf_text_to_bool("no", &b)); ATF_REQUIRE(!b);
348240116Smarcel    RE(atf_text_to_bool("NO", &b)); ATF_REQUIRE(!b);
349240116Smarcel
350240116Smarcel    b = false;
351240116Smarcel    REQUIRE_ERROR(atf_text_to_bool("", &b));
352240116Smarcel    ATF_REQUIRE(!b);
353240116Smarcel    b = true;
354240116Smarcel    REQUIRE_ERROR(atf_text_to_bool("", &b));
355240116Smarcel    ATF_REQUIRE(b);
356240116Smarcel
357240116Smarcel    b = false;
358240116Smarcel    REQUIRE_ERROR(atf_text_to_bool("tru", &b));
359240116Smarcel    ATF_REQUIRE(!b);
360240116Smarcel    b = true;
361240116Smarcel    REQUIRE_ERROR(atf_text_to_bool("tru", &b));
362240116Smarcel    ATF_REQUIRE(b);
363240116Smarcel
364240116Smarcel    b = false;
365240116Smarcel    REQUIRE_ERROR(atf_text_to_bool("true2", &b));
366240116Smarcel    ATF_REQUIRE(!b);
367240116Smarcel    b = true;
368240116Smarcel    REQUIRE_ERROR(atf_text_to_bool("true2", &b));
369240116Smarcel    ATF_REQUIRE(b);
370240116Smarcel
371240116Smarcel    b = false;
372240116Smarcel    REQUIRE_ERROR(atf_text_to_bool("fals", &b));
373240116Smarcel    ATF_REQUIRE(!b);
374240116Smarcel    b = true;
375240116Smarcel    REQUIRE_ERROR(atf_text_to_bool("fals", &b));
376240116Smarcel    ATF_REQUIRE(b);
377240116Smarcel
378240116Smarcel    b = false;
379240116Smarcel    REQUIRE_ERROR(atf_text_to_bool("false2", &b));
380240116Smarcel    ATF_REQUIRE(!b);
381240116Smarcel    b = true;
382240116Smarcel    REQUIRE_ERROR(atf_text_to_bool("false2", &b));
383240116Smarcel    ATF_REQUIRE(b);
384240116Smarcel}
385240116Smarcel
386240116SmarcelATF_TC(to_long);
387240116SmarcelATF_TC_HEAD(to_long, tc)
388240116Smarcel{
389240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_long function");
390240116Smarcel}
391240116SmarcelATF_TC_BODY(to_long, tc)
392240116Smarcel{
393240116Smarcel    long l;
394240116Smarcel
395240116Smarcel    RE(atf_text_to_long("0", &l)); ATF_REQUIRE_EQ(l, 0);
396240116Smarcel    RE(atf_text_to_long("-5", &l)); ATF_REQUIRE_EQ(l, -5);
397240116Smarcel    RE(atf_text_to_long("5", &l)); ATF_REQUIRE_EQ(l, 5);
398240116Smarcel    RE(atf_text_to_long("123456789", &l)); ATF_REQUIRE_EQ(l, 123456789);
399240116Smarcel
400240116Smarcel    l = 1212;
401240116Smarcel    REQUIRE_ERROR(atf_text_to_long("", &l));
402240116Smarcel    ATF_REQUIRE_EQ(l, 1212);
403240116Smarcel    REQUIRE_ERROR(atf_text_to_long("foo", &l));
404240116Smarcel    ATF_REQUIRE_EQ(l, 1212);
405240116Smarcel    REQUIRE_ERROR(atf_text_to_long("1234x", &l));
406240116Smarcel    ATF_REQUIRE_EQ(l, 1212);
407240116Smarcel}
408240116Smarcel
409240116Smarcel/* ---------------------------------------------------------------------
410240116Smarcel * Main.
411240116Smarcel * --------------------------------------------------------------------- */
412240116Smarcel
413240116SmarcelATF_TP_ADD_TCS(tp)
414240116Smarcel{
415240116Smarcel    ATF_TP_ADD_TC(tp, for_each_word);
416240116Smarcel    ATF_TP_ADD_TC(tp, format);
417240116Smarcel    ATF_TP_ADD_TC(tp, format_ap);
418240116Smarcel    ATF_TP_ADD_TC(tp, split);
419240116Smarcel    ATF_TP_ADD_TC(tp, split_delims);
420240116Smarcel    ATF_TP_ADD_TC(tp, to_bool);
421240116Smarcel    ATF_TP_ADD_TC(tp, to_long);
422240116Smarcel
423240116Smarcel    return atf_no_error();
424240116Smarcel}
425