1 /* 2 * Automated Testing Framework (atf) 3 * 4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 34 #include <atf-c.h> 35 36 #include "sanity.h" 37 #include "test_helpers.h" 38 #include "text.h" 39 40 /* --------------------------------------------------------------------- 41 * Auxiliary functions. 42 * --------------------------------------------------------------------- */ 43 44 #define REQUIRE_ERROR(exp) \ 45 do { \ 46 atf_error_t err = exp; \ 47 ATF_REQUIRE(atf_is_error(err)); \ 48 atf_error_free(err); \ 49 } while (0) 50 51 static 52 size_t 53 array_size(const char *words[]) 54 { 55 size_t count; 56 const char **word; 57 58 count = 0; 59 for (word = words; *word != NULL; word++) 60 count++; 61 62 return count; 63 } 64 65 static 66 void 67 check_split(const char *str, const char *delim, const char *words[]) 68 { 69 atf_list_t list; 70 const char **word; 71 size_t i; 72 73 printf("Splitting '%s' with delimiter '%s'\n", str, delim); 74 CE(atf_text_split(str, delim, &list)); 75 76 printf("Expecting %zd words\n", array_size(words)); 77 ATF_CHECK_EQ(atf_list_size(&list), array_size(words)); 78 79 for (word = words, i = 0; *word != NULL; word++, i++) { 80 printf("Word at position %zd should be '%s'\n", i, words[i]); 81 ATF_CHECK_STREQ((const char *)atf_list_index_c(&list, i), words[i]); 82 } 83 84 atf_list_fini(&list); 85 } 86 87 static 88 atf_error_t 89 word_acum(const char *word, void *data) 90 { 91 char *acum = data; 92 93 strcat(acum, word); 94 95 return atf_no_error(); 96 } 97 98 static 99 atf_error_t 100 word_count(const char *word ATF_DEFS_ATTRIBUTE_UNUSED, void *data) 101 { 102 size_t *counter = data; 103 104 (*counter)++; 105 106 return atf_no_error(); 107 } 108 109 struct fail_at { 110 int failpos; 111 int curpos; 112 }; 113 114 static 115 atf_error_t 116 word_fail_at(const char *word ATF_DEFS_ATTRIBUTE_UNUSED, void *data) 117 { 118 struct fail_at *fa = data; 119 atf_error_t err; 120 121 if (fa->failpos == fa->curpos) 122 err = atf_no_memory_error(); /* Just a random error. */ 123 else { 124 fa->curpos++; 125 err = atf_no_error(); 126 } 127 128 return err; 129 } 130 131 /* --------------------------------------------------------------------- 132 * Test cases for the free functions. 133 * --------------------------------------------------------------------- */ 134 135 ATF_TC(for_each_word); 136 ATF_TC_HEAD(for_each_word, tc) 137 { 138 atf_tc_set_md_var(tc, "descr", "Checks the atf_text_for_each_word" 139 "function"); 140 } 141 ATF_TC_BODY(for_each_word, tc) 142 { 143 size_t cnt; 144 char acum[1024]; 145 146 cnt = 0; 147 strcpy(acum, ""); 148 RE(atf_text_for_each_word("1 2 3", " ", word_count, &cnt)); 149 RE(atf_text_for_each_word("1 2 3", " ", word_acum, acum)); 150 ATF_REQUIRE(cnt == 3); 151 ATF_REQUIRE(strcmp(acum, "123") == 0); 152 153 cnt = 0; 154 strcpy(acum, ""); 155 RE(atf_text_for_each_word("1 2 3", ".", word_count, &cnt)); 156 RE(atf_text_for_each_word("1 2 3", ".", word_acum, acum)); 157 ATF_REQUIRE(cnt == 1); 158 ATF_REQUIRE(strcmp(acum, "1 2 3") == 0); 159 160 cnt = 0; 161 strcpy(acum, ""); 162 RE(atf_text_for_each_word("1 2 3 4 5", " ", word_count, &cnt)); 163 RE(atf_text_for_each_word("1 2 3 4 5", " ", word_acum, acum)); 164 ATF_REQUIRE(cnt == 5); 165 ATF_REQUIRE(strcmp(acum, "12345") == 0); 166 167 cnt = 0; 168 strcpy(acum, ""); 169 RE(atf_text_for_each_word("1 2.3.4 5", " .", word_count, &cnt)); 170 RE(atf_text_for_each_word("1 2.3.4 5", " .", word_acum, acum)); 171 ATF_REQUIRE(cnt == 5); 172 ATF_REQUIRE(strcmp(acum, "12345") == 0); 173 174 { 175 struct fail_at fa; 176 fa.failpos = 3; 177 fa.curpos = 0; 178 atf_error_t err = atf_text_for_each_word("a b c d e", " ", 179 word_fail_at, &fa); 180 ATF_REQUIRE(atf_is_error(err)); 181 ATF_REQUIRE(atf_error_is(err, "no_memory")); 182 ATF_REQUIRE(fa.curpos == 3); 183 atf_error_free(err); 184 } 185 } 186 187 ATF_TC(format); 188 ATF_TC_HEAD(format, tc) 189 { 190 atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form " 191 "strings using a variable parameters list"); 192 } 193 ATF_TC_BODY(format, tc) 194 { 195 char *str; 196 atf_error_t err; 197 198 err = atf_text_format(&str, "%s %s %d", "Test", "string", 1); 199 ATF_REQUIRE(!atf_is_error(err)); 200 ATF_REQUIRE(strcmp(str, "Test string 1") == 0); 201 free(str); 202 } 203 204 static 205 void 206 format_ap(char **dest, const char *fmt, ...) 207 { 208 va_list ap; 209 atf_error_t err; 210 211 va_start(ap, fmt); 212 err = atf_text_format_ap(dest, fmt, ap); 213 va_end(ap); 214 215 ATF_REQUIRE(!atf_is_error(err)); 216 } 217 218 ATF_TC(format_ap); 219 ATF_TC_HEAD(format_ap, tc) 220 { 221 atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form " 222 "strings using a va_list argument"); 223 } 224 ATF_TC_BODY(format_ap, tc) 225 { 226 char *str; 227 228 format_ap(&str, "%s %s %d", "Test", "string", 1); 229 ATF_REQUIRE(strcmp(str, "Test string 1") == 0); 230 free(str); 231 } 232 233 ATF_TC(split); 234 ATF_TC_HEAD(split, tc) 235 { 236 atf_tc_set_md_var(tc, "descr", "Checks the split function"); 237 } 238 ATF_TC_BODY(split, tc) 239 { 240 { 241 const char *words[] = { NULL }; 242 check_split("", " ", words); 243 } 244 245 { 246 const char *words[] = { NULL }; 247 check_split(" ", " ", words); 248 } 249 250 { 251 const char *words[] = { NULL }; 252 check_split(" ", " ", words); 253 } 254 255 { 256 const char *words[] = { "a", "b", NULL }; 257 check_split("a b", " ", words); 258 } 259 260 { 261 const char *words[] = { "a", "b", "c", "d", NULL }; 262 check_split("a b c d", " ", words); 263 } 264 265 { 266 const char *words[] = { "foo", "bar", NULL }; 267 check_split("foo bar", " ", words); 268 } 269 270 { 271 const char *words[] = { "foo", "bar", "baz", "foobar", NULL }; 272 check_split("foo bar baz foobar", " ", words); 273 } 274 275 { 276 const char *words[] = { "foo", "bar", NULL }; 277 check_split(" foo bar", " ", words); 278 } 279 280 { 281 const char *words[] = { "foo", "bar", NULL }; 282 check_split("foo bar", " ", words); 283 } 284 285 { 286 const char *words[] = { "foo", "bar", NULL }; 287 check_split("foo bar ", " ", words); 288 } 289 290 { 291 const char *words[] = { "foo", "bar", NULL }; 292 check_split(" foo bar ", " ", words); 293 } 294 } 295 296 ATF_TC(split_delims); 297 ATF_TC_HEAD(split_delims, tc) 298 { 299 atf_tc_set_md_var(tc, "descr", "Checks the split function using " 300 "different delimiters"); 301 } 302 ATF_TC_BODY(split_delims, tc) 303 { 304 305 { 306 const char *words[] = { NULL }; 307 check_split("", "/", words); 308 } 309 310 { 311 const char *words[] = { " ", NULL }; 312 check_split(" ", "/", words); 313 } 314 315 { 316 const char *words[] = { " ", NULL }; 317 check_split(" ", "/", words); 318 } 319 320 { 321 const char *words[] = { "a", "b", NULL }; 322 check_split("a/b", "/", words); 323 } 324 325 { 326 const char *words[] = { "a", "bcd", "ef", NULL }; 327 check_split("aLONGDELIMbcdLONGDELIMef", "LONGDELIM", words); 328 } 329 } 330 331 ATF_TC(to_bool); 332 ATF_TC_HEAD(to_bool, tc) 333 { 334 atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_bool function"); 335 } 336 ATF_TC_BODY(to_bool, tc) 337 { 338 bool b; 339 340 RE(atf_text_to_bool("true", &b)); ATF_REQUIRE(b); 341 RE(atf_text_to_bool("TRUE", &b)); ATF_REQUIRE(b); 342 RE(atf_text_to_bool("yes", &b)); ATF_REQUIRE(b); 343 RE(atf_text_to_bool("YES", &b)); ATF_REQUIRE(b); 344 345 RE(atf_text_to_bool("false", &b)); ATF_REQUIRE(!b); 346 RE(atf_text_to_bool("FALSE", &b)); ATF_REQUIRE(!b); 347 RE(atf_text_to_bool("no", &b)); ATF_REQUIRE(!b); 348 RE(atf_text_to_bool("NO", &b)); ATF_REQUIRE(!b); 349 350 b = false; 351 REQUIRE_ERROR(atf_text_to_bool("", &b)); 352 ATF_REQUIRE(!b); 353 b = true; 354 REQUIRE_ERROR(atf_text_to_bool("", &b)); 355 ATF_REQUIRE(b); 356 357 b = false; 358 REQUIRE_ERROR(atf_text_to_bool("tru", &b)); 359 ATF_REQUIRE(!b); 360 b = true; 361 REQUIRE_ERROR(atf_text_to_bool("tru", &b)); 362 ATF_REQUIRE(b); 363 364 b = false; 365 REQUIRE_ERROR(atf_text_to_bool("true2", &b)); 366 ATF_REQUIRE(!b); 367 b = true; 368 REQUIRE_ERROR(atf_text_to_bool("true2", &b)); 369 ATF_REQUIRE(b); 370 371 b = false; 372 REQUIRE_ERROR(atf_text_to_bool("fals", &b)); 373 ATF_REQUIRE(!b); 374 b = true; 375 REQUIRE_ERROR(atf_text_to_bool("fals", &b)); 376 ATF_REQUIRE(b); 377 378 b = false; 379 REQUIRE_ERROR(atf_text_to_bool("false2", &b)); 380 ATF_REQUIRE(!b); 381 b = true; 382 REQUIRE_ERROR(atf_text_to_bool("false2", &b)); 383 ATF_REQUIRE(b); 384 } 385 386 ATF_TC(to_long); 387 ATF_TC_HEAD(to_long, tc) 388 { 389 atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_long function"); 390 } 391 ATF_TC_BODY(to_long, tc) 392 { 393 long l; 394 395 RE(atf_text_to_long("0", &l)); ATF_REQUIRE_EQ(l, 0); 396 RE(atf_text_to_long("-5", &l)); ATF_REQUIRE_EQ(l, -5); 397 RE(atf_text_to_long("5", &l)); ATF_REQUIRE_EQ(l, 5); 398 RE(atf_text_to_long("123456789", &l)); ATF_REQUIRE_EQ(l, 123456789); 399 400 l = 1212; 401 REQUIRE_ERROR(atf_text_to_long("", &l)); 402 ATF_REQUIRE_EQ(l, 1212); 403 REQUIRE_ERROR(atf_text_to_long("foo", &l)); 404 ATF_REQUIRE_EQ(l, 1212); 405 REQUIRE_ERROR(atf_text_to_long("1234x", &l)); 406 ATF_REQUIRE_EQ(l, 1212); 407 } 408 409 /* --------------------------------------------------------------------- 410 * Main. 411 * --------------------------------------------------------------------- */ 412 413 ATF_TP_ADD_TCS(tp) 414 { 415 ATF_TP_ADD_TC(tp, for_each_word); 416 ATF_TP_ADD_TC(tp, format); 417 ATF_TP_ADD_TC(tp, format_ap); 418 ATF_TP_ADD_TC(tp, split); 419 ATF_TP_ADD_TC(tp, split_delims); 420 ATF_TP_ADD_TC(tp, to_bool); 421 ATF_TP_ADD_TC(tp, to_long); 422 423 return atf_no_error(); 424 } 425