cont
[protos/libecoli.git] / lib / ecoli_test.c
1 /*
2  * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the University of California, Berkeley nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <assert.h>
32
33 #include <ecoli_log.h>
34 #include <ecoli_malloc.h>
35 #include <ecoli_test.h>
36 #include <ecoli_strvec.h>
37 #include <ecoli_tk.h>
38
39 static struct ec_test_list test_list = TAILQ_HEAD_INITIALIZER(test_list);
40
41 /* register a driver */
42 void ec_test_register(struct ec_test *test)
43 {
44         TAILQ_INSERT_TAIL(&test_list, test, next);
45 }
46
47 int ec_test_check_tk_parse(const struct ec_tk *tk, int expected, ...)
48 {
49         struct ec_parsed_tk *p;
50         struct ec_strvec *vec = NULL;
51         const char *s;
52         int ret = -1, match;
53         va_list ap;
54
55         va_start(ap, expected);
56
57         /* build a string vector */
58         vec = ec_strvec_new();
59         if (vec == NULL)
60                 goto out;
61
62         for (s = va_arg(ap, const char *);
63              s != EC_TK_ENDLIST;
64              s = va_arg(ap, const char *)) {
65                 if (s == NULL)
66                         goto out;
67
68                 if (ec_strvec_add(vec, s) < 0)
69                         goto out;
70         }
71
72         p = ec_tk_parse_tokens(tk, vec);
73         /* XXX only for debug */
74         ec_parsed_tk_dump(stdout, p);
75         if (p == NULL) {
76                 ec_log(EC_LOG_ERR, "parsed_tk is NULL\n");
77         }
78         if (ec_parsed_tk_matches(p))
79                 match = ec_parsed_tk_len(p);
80         else
81                 match = -1;
82         if (expected == match) {
83                 ret = 0;
84         } else {
85                 ec_log(EC_LOG_ERR,
86                         "tk parsed len (%d) does not match expected (%d)\n",
87                         match, expected);
88         }
89
90         ec_parsed_tk_free(p);
91
92 out:
93         ec_strvec_free(vec);
94         va_end(ap);
95         return ret;
96 }
97
98 int ec_test_check_tk_complete(const struct ec_tk *tk, ...)
99 {
100         struct ec_completed_tk *c = NULL;
101         struct ec_completed_tk_elt *elt;
102         struct ec_strvec *vec = NULL;
103         const char *s, *expected;
104         int ret = 0;
105         unsigned int count = 0;
106         va_list ap;
107
108         va_start(ap, tk);
109
110         /* build a string vector */
111         vec = ec_strvec_new();
112         if (vec == NULL)
113                 goto out;
114
115         for (s = va_arg(ap, const char *);
116              s != EC_TK_ENDLIST;
117              s = va_arg(ap, const char *)) {
118                 if (s == NULL)
119                         goto out;
120
121                 if (ec_strvec_add(vec, s) < 0)
122                         goto out;
123         }
124
125         c = ec_tk_complete_tokens(tk, vec);
126         if (c == NULL) {
127                 ret = -1;
128                 goto out;
129         }
130
131         for (s = va_arg(ap, const char *);
132              s != EC_TK_ENDLIST;
133              s = va_arg(ap, const char *)) {
134                 if (s == NULL) {
135                         ret = -1;
136                         goto out;
137                 }
138
139                 count++;
140                 TAILQ_FOREACH(elt, &c->elts, next) {
141                         /* only check matching completions */
142                         if (elt->add != NULL && strcmp(elt->add, s) == 0)
143                                 break;
144                 }
145
146                 if (elt == NULL) {
147                         ec_log(EC_LOG_ERR,
148                                 "completion <%s> not in list\n", s);
149                         ret = -1;
150                 }
151         }
152
153         if (count != ec_completed_tk_count_match(c)) {
154                 ec_log(EC_LOG_ERR,
155                         "nb_completion (%d) does not match (%d)\n",
156                         count, ec_completed_tk_count_match(c));
157                 ec_completed_tk_dump(stdout, c);
158                 ret = -1;
159         }
160
161
162         expected = va_arg(ap, const char *);
163         s = ec_completed_tk_smallest_start(c);
164         if (strcmp(s, expected)) {
165                 ret = -1;
166                 ec_log(EC_LOG_ERR,
167                         "should complete with <%s> but completes with <%s>\n",
168                         expected, s);
169         }
170
171 out:
172         ec_strvec_free(vec);
173         ec_completed_tk_free(c);
174         va_end(ap);
175         return ret;
176 }
177
178 int ec_test_all(void)
179 {
180         struct ec_test *test;
181         int ret = 0;
182
183         TAILQ_FOREACH(test, &test_list, next) {
184                 ec_log(EC_LOG_INFO, "== starting test %-20s\n", test->name);
185
186                 if (test->test() == 0) {
187                         ec_log(EC_LOG_INFO, "== test %-20s success\n",
188                                 test->name);
189                 } else {
190                         ec_log(EC_LOG_INFO, "== test %-20s failed\n",
191                                 test->name);
192                         ret = -1;
193                 }
194         }
195
196         return ret;
197 }