OpenDNSSEC-enforcer  1.4.9
test_string_util.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008-2009 Nominet UK. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. 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  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
27 /*+
28  * Filename: test_string_util.c
29  *
30  * Description:
31  * This modules holds the unit tests for the functions in string_util.c.
32  * module.
33  *
34  * The test program makes use of the CUnit framework, as described in
35  * http://cunit.sourceforge.net
36 -*/
37 
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 
42 #include "CUnit/Basic.h"
43 
44 #include "ksm/memory.h"
45 #include "ksm/string_util.h"
46 #include "test_routines.h"
47 
48 
49 
50 
51 /*
52  * TestCompare - Compare Strings
53  * TestCompare - Compare Strings N characters
54  *
55  * Description:
56  * Compares two strings. Unlike strcmp, this can cope with NULL strings,
57  * and considers both equal if both are NULL.
58  *
59  * Although the CU_ASSERT_TRUE of the result could be done here, it
60  * is actually done in the caller so that if a test fails, CUnit will
61  * give some indication of the failing test.
62  *
63  * Arguments:
64  * const char* actual (input)
65  * The string being compared.
66  *
67  * const char* expected (input)
68  * The expected value of the string.
69  *
70  * size_t count (TestCompareN only)
71  * Length of sterings to compare.
72  *
73  * Returns:
74  * int
75  * 1 Strings were identical
76  * 0 Strings were different
77  */
78 
79 static int TestCompareN(const char* actual, const char* expected, size_t count)
80 {
81  int ok; /* Success status */
82 
83  if ((! actual) && (! expected)) {
84  ok = 1;
85  }
86  else if (actual && (! expected)) {
87  ok = 0;
88  }
89  else if ((! actual) && expected) {
90  ok = 0;
91  }
92  else {
93  ok = (memcmp(actual, expected, count) == 0);
94  }
95 
96  return ok;
97 }
98 
99 static int TestCompare(const char* actual, const char* expected)
100 {
101  int ok; /* Success status */
102 
103  if ((! actual) && (! expected)) {
104  ok = 1;
105  }
106  else if (actual && (! expected)) {
107  ok = 0;
108  }
109  else if ((! actual) && expected) {
110  ok = 0;
111  }
112  else {
113  ok = (strcmp(actual, expected) == 0);
114  }
115 
116  return ok;
117 }
118 
119 
120 
121 /*
122  * TestStrXxx - Test Routines
123  *
124  * Description:
125  * A set of routines, each testing one particular string utility routine.
126  * Each utility routine is tested by two routines:
127  *
128  * TestStrXxx Tests utillity routine for one string
129  * TestStrXxxExecute Calls TestStrXxx for a variety of strings.
130  *
131  * Arguments:
132  * Varies.
133  */
134 
135 
136 /* StrStrdup */
137 
138 static void TestStrStrdupExecute(const char* test)
139 {
140  char* testdup = StrStrdup(test);
141  CU_ASSERT_TRUE(TestCompare(testdup, test == NULL ? "" : test));
142  StrFree(testdup);
143 
144  return;
145 }
146 
147 static void TestStrStrdup(void)
148 {
149  TestStrStrdupExecute(NULL);
150  TestStrStrdupExecute("");
151  TestStrStrdupExecute(" ");
152  TestStrStrdupExecute("a test string");
153 
154  return;
155 }
156 
157 /* StrStrncpy */
158 
159 static void TestStrStrncpyExecute(const char* test, const char* expected,
160  size_t destlen)
161 {
162  char* dest = MemMalloc(destlen); /* Create target area */
163  StrStrncpy(dest, test, destlen); /* Copy data */
164  CU_ASSERT_TRUE(TestCompare(dest, expected));/* Compare */
165  MemFree(dest); /* Free up memory */
166 }
167 
168 static void TestStrStrncpy(void)
169 {
170  char dummy[100];
171  static const char* TEST = "A dummy string"; /* Must be < sizeof(dummy) */
172 
173  TestStrStrncpyExecute("alpha", "alpha", 100); /* More than enough space */
174  TestStrStrncpyExecute("beta", "beta", 5); /* Enough space */
175  TestStrStrncpyExecute("gamma", "gamm", 5); /* 1 character too small */
176  TestStrStrncpyExecute("delta", "d", 2); /* Very small */
177  TestStrStrncpyExecute("epsilon", "", 1); /* Minimum possible */
178 
179  /* Finally some tests on what should be no-ops */
180 
181  strcpy(dummy, TEST);
182  StrStrncpy(dummy, NULL, 100);
183  CU_ASSERT_STRING_EQUAL(dummy, "");
184 
185  strcpy(dummy, TEST);
186  StrStrncpy(dummy, "xyz", 0);
187  CU_ASSERT_STRING_EQUAL(dummy, TEST);
188 
189  /*
190  * The final check tests that the routine does not generate a segmentation
191  * fault if the destination is NULL.
192  */
193 
194  StrStrncpy(NULL, "xyz", 52);
195 
196  return;
197 }
198 
199 /* StrStrncat */
200 
201 static void TestStrStrncatExecute(const char* dst, const char* src,
202  size_t dstlen, const char* expected)
203 {
204  char* newdst = NULL;
205 
206  if (dst) {
207  newdst = MemMalloc(dstlen); /* Create target area */
208  StrStrncpy(newdst, dst, dstlen); /* Copy data */
209  }
210  StrStrncat(newdst, src, dstlen);
211  CU_ASSERT_TRUE(TestCompare(newdst, expected));/* Compare */
212 
213  MemFree(newdst); /* Free up memory */
214 }
215 
216 static void TestStrStrncat(void)
217 {
218  TestStrStrncatExecute("alpha", "beta", 100, "alphabeta");
219  TestStrStrncatExecute("alpha", "beta", 6, "alpha");
220  TestStrStrncatExecute("alpha", "beta", 7, "alphab");
221  TestStrStrncatExecute("alpha", "beta", 8, "alphabe");
222  TestStrStrncatExecute("alpha", "beta", 9, "alphabet");
223  TestStrStrncatExecute("alpha", "beta", 10, "alphabeta");
224  TestStrStrncatExecute("alpha", "beta", 11, "alphabeta");
225 
226  TestStrStrncatExecute("alpha ", "beta", 9, "alpha be");
227  TestStrStrncatExecute("alpha ", "beta", 10, "alpha bet");
228  TestStrStrncatExecute("alpha ", "beta", 11, "alpha beta");
229  TestStrStrncatExecute("alpha ", "beta", 12, "alpha beta");
230 
231  TestStrStrncatExecute("", "beta", 1, "");
232  TestStrStrncatExecute("", "beta", 2, "b");
233  TestStrStrncatExecute("", "beta", 3, "be");
234  TestStrStrncatExecute("", "beta", 4, "bet");
235  TestStrStrncatExecute("", "beta", 5, "beta");
236  TestStrStrncatExecute("", "beta", 6, "beta");
237 
238  TestStrStrncatExecute(NULL, "gamma", 6, NULL);
239 
240  return;
241 }
242 
243 /* StrUncomment */
244 
245 static void TestStrUncommentExecute(const char* test, const char* expected)
246 {
247  char* testdup = test ? strdup(test) : NULL;
248 
249  StrUncomment(testdup);
250  CU_ASSERT_TRUE(TestCompare(testdup, expected));
251 
252  free(testdup);
253 
254  return;
255 }
256 
257 static void TestStrUncomment(void)
258 {
259  TestStrUncommentExecute(NULL, NULL);
260  TestStrUncommentExecute("", "");
261  TestStrUncommentExecute(" \t ", " \t ");
262  TestStrUncommentExecute("This is a string with a #comment",
263  "This is a string with a ");
264  TestStrUncommentExecute("This is a string with a # ## comment",
265  "This is a string with a ");
266  TestStrUncommentExecute("#This is a leading comment", "");
267  TestStrUncommentExecute("\t\t#comment", "\t\t");
268  TestStrUncommentExecute("A string with no comment",
269  "A string with no comment");
270 
271  return;
272 }
273 
274 /* StrWhitespace */
275 
276 static void TestStrWhitespaceExecute(const char* test, const char* expected)
277 {
278  char* testdup = test ? strdup(test) : NULL;
279 
280  StrWhitespace(testdup);
281  CU_ASSERT_TRUE(TestCompare(testdup, expected));
282 
283  free(testdup);
284 
285  return;
286 }
287 
288 static void TestStrWhitespace(void)
289 {
290  TestStrWhitespaceExecute(NULL, NULL);
291  TestStrWhitespaceExecute("", "");
292  TestStrWhitespaceExecute(" \t ", " ");
293  TestStrWhitespaceExecute(" \r\n", " ");
294  TestStrWhitespaceExecute("A\tstring\twith\tembedded\ttabs",
295  "A string with embedded tabs");
296  TestStrWhitespaceExecute("no_whitespace", "no_whitespace");
297  TestStrWhitespaceExecute("\r\nwhitespace\t\t", " whitespace ");
298 
299  return;
300 }
301 
302 /* StrTrimR */
303 
304 static void TestStrTrimRExecute(const char* test, const char* expected)
305 {
306  char* testdup = test ? strdup(test) : NULL;
307 
308  StrTrimR(testdup);
309  CU_ASSERT_TRUE(TestCompare(testdup, expected));
310 
311  free(testdup);
312 
313  return;
314 }
315 
316 static void TestStrTrimR(void)
317 {
318  TestStrTrimRExecute(NULL, NULL);
319  TestStrTrimRExecute("", "");
320  TestStrTrimRExecute("\t\tabc", "\t\tabc");
321  TestStrTrimRExecute("abc\t\t", "abc");
322  TestStrTrimRExecute(" alpha ", " alpha");
323  TestStrTrimRExecute(" alpha beta\n", " alpha beta");
324 
325  return;
326 }
327 
328 /* StrTrimL */
329 
330 static void TestStrTrimLExecute(const char* test, const char* expected)
331 {
332  char* testdup = test ? strdup(test) : NULL;
333 
334  char* trimmed = StrTrimL(testdup);
335  CU_ASSERT_TRUE(TestCompare(trimmed, expected));
336 
337  free(testdup);
338 
339  return;
340 }
341 
342 static void TestStrTrimL(void)
343 {
344  TestStrTrimLExecute(NULL, NULL);
345  TestStrTrimLExecute("", "");
346  TestStrTrimLExecute("\t\tabc", "abc");
347  TestStrTrimLExecute("abc\t\t", "abc\t\t");
348  TestStrTrimLExecute(" alpha ", "alpha ");
349  TestStrTrimLExecute(" alpha beta\n", "alpha beta\n");
350 
351  return;
352 }
353 
354 /* StrTrim */
355 
356 static void TestStrTrimExecute(const char* test, const char* expected)
357 {
358  char* testdup = test ? strdup(test) : NULL;
359 
360  char* modstr = StrTrim(testdup);
361  CU_ASSERT_TRUE(TestCompare(modstr, expected));
362 
363  free(testdup);
364 
365  return;
366 }
367 
368 static void TestStrTrim(void)
369 {
370  TestStrTrimExecute(NULL, NULL);
371  TestStrTrimExecute("", "");
372  TestStrTrimExecute("\t\tabc", "abc");
373  TestStrTrimExecute("abc\t\t", "abc");
374  TestStrTrimExecute(" alpha ", "alpha");
375  TestStrTrimExecute(" alpha beta\n", "alpha beta");
376 
377  return;
378 }
379 
380 /* StrToLower */
381 
382 static void TestStrToLowerExecute(const char* test, const char* expected)
383 {
384  char* testdup = test ? strdup(test) : NULL;
385 
386  size_t length = StrToLower(testdup);
387  CU_ASSERT_TRUE(TestCompare(testdup, expected));
388  if (test) {
389  CU_ASSERT_EQUAL(length, strlen(expected));
390  }
391  else {
392  CU_ASSERT_EQUAL(length, 0);
393  }
394 
395  free(testdup);
396 
397  return;
398 }
399 
400 static void TestStrToLower(void)
401 {
402  TestStrToLowerExecute(NULL, NULL);
403  TestStrToLowerExecute("abc", "abc");
404  TestStrToLowerExecute("ABC", "abc");
405  TestStrToLowerExecute("AbC", "abc");
406  TestStrToLowerExecute("AbC d e F", "abc d e f");
407 
408  return;
409 }
410 
411 
412 /* StrToUpper */
413 
414 static void TestStrToUpperExecute(const char* test, const char* expected)
415 {
416  char* testdup = test ? strdup(test) : NULL;
417 
418  size_t length = StrToUpper(testdup);
419  CU_ASSERT_TRUE(TestCompare(testdup, expected));
420  if (test) {
421  CU_ASSERT_EQUAL(length, strlen(expected));
422  }
423  else {
424  CU_ASSERT_EQUAL(length, 0);
425  }
426 
427  free(testdup);
428 
429  return;
430 }
431 
432 static void TestStrToUpper(void)
433 {
434  TestStrToUpperExecute(NULL, NULL);
435  TestStrToUpperExecute("abc", "ABC");
436  TestStrToUpperExecute("ABC", "ABC");
437  TestStrToUpperExecute("AbC", "ABC");
438  TestStrToUpperExecute("AbC d e F", "ABC D E F");
439 
440  return;
441 }
442 
443 
444 /* StrReplaceChar */
445 
446 static void TestStrReplaceCharExecute(const char* test, const char* expected,
447  char search, char replace, int expected_count)
448 {
449  char* testdup = test ? strdup(test) : NULL;
450 
451  int count = StrReplaceChar(testdup, search, replace);
452  CU_ASSERT_TRUE(TestCompare(testdup, expected));
453  CU_ASSERT_EQUAL(count, expected_count);
454 
455  free(testdup);
456 
457  return;
458 }
459 
460 static void TestStrReplaceChar(void)
461 {
462  TestStrReplaceCharExecute(NULL, NULL, 'a', 'b', 0);
463  TestStrReplaceCharExecute("ABCDEF", "ABCDEF", 'a', 'b', 0);
464  TestStrReplaceCharExecute(",abc", "@abc", ',', '@', 1);
465  TestStrReplaceCharExecute("abc,", "abc@", ',', '@', 1);
466  TestStrReplaceCharExecute(",abc,", "@abc@", ',', '@', 2);
467  TestStrReplaceCharExecute("ab,c", "ab@c", ',', '@', 1);
468  TestStrReplaceCharExecute("abacadae", "ebecedee", 'a', 'e', 4);
469 
470  return;
471 }
472 
473 
474 /* StrReplaceCharN */
475 
476 static void TestStrReplaceCharNExecute(const char* test, size_t testlen,
477  const char* expected, char search, char replace, int expected_count)
478 {
479  int count = 0; /* Replacement count */
480  char* testdup = NULL; /* String copy */
481 
482  if (test) {
483  testdup = MemMalloc(testlen + 1);
484  memcpy(testdup, test, testlen);
485  testdup[testlen] = '\0';
486  }
487 
488  count = StrReplaceCharN(testdup, testlen, search, replace);
489  CU_ASSERT_TRUE(TestCompareN(testdup, expected, testlen));
490  CU_ASSERT_EQUAL(count, expected_count);
491  if (testdup) {
492  MemFree(testdup);
493  }
494 
495  return;
496 }
497 
498 static void TestStrReplaceCharN(void)
499 {
500  TestStrReplaceCharNExecute(NULL, 5, NULL, 'a', 'b', 0);
501  TestStrReplaceCharNExecute("ABCDEF", 6, "ABCDEF", 'a', 'b', 0);
502  TestStrReplaceCharNExecute("ABCDEF", 6, "BBCDEF", 'A', 'B', 1);
503  TestStrReplaceCharNExecute("ABC\0EF", 6, "ABCCEF", '\0', 'C', 1);
504  TestStrReplaceCharNExecute("ABC\0EF\0", 7, "ABCCEFC", '\0', 'C', 2);
505  TestStrReplaceCharNExecute("\0", 1, " ", '\0', ' ', 1);
506 
507  return;
508 }
509 
510 
511 /* StrTrimmedLength */
512 
513 static void TestStrTrimmedLengthExecute(const char* test, size_t expected)
514 {
515  CU_ASSERT_EQUAL(StrTrimmedLength(test), expected);
516 
517  return;
518 }
519 
520 static void TestStrTrimmedLength(void)
521 {
522  TestStrTrimmedLengthExecute(NULL, 0);
523  TestStrTrimmedLengthExecute("", 0);
524  TestStrTrimmedLengthExecute(" ", 0);
525  TestStrTrimmedLengthExecute("\n\n\r\t", 0);
526  TestStrTrimmedLengthExecute("abc", 3);
527  TestStrTrimmedLengthExecute(" abc", 3);
528  TestStrTrimmedLengthExecute("defg \n", 4);
529  TestStrTrimmedLengthExecute("\t\tabcdef\t ", 6);
530  TestStrTrimmedLengthExecute(" abcdefg ", 7);
531  TestStrTrimmedLengthExecute(" a b c d e f ", 11);
532  TestStrTrimmedLengthExecute(" a\r\tb", 4);
533  TestStrTrimmedLengthExecute(" xy zzy ", 6);
534 
535  return;
536 }
537 
538 
539 /*
540  * TestStr - Create Test Suite
541  *
542  * Description:
543  * Adds the string test suite to the CUnit test registry
544  * and adds all the tests to it.
545  *
546  * Arguments:
547  * None.
548  *
549  * Returns:
550  * int
551  * Return status. 0 => Success.
552  */
553 
554 int TestStr(void); /* Declaration */
555 int TestStr(void)
556 {
557  struct test_testdef tests[] = {
558  {"StrReplaceCharN", TestStrReplaceCharN},
559  {"StrReplaceChar", TestStrReplaceChar},
560  {"StrStrdup", TestStrStrdup},
561  {"StrStrncpy", TestStrStrncpy},
562  {"StrStrncat", TestStrStrncat},
563  {"StrToLower", TestStrToLower},
564  {"StrToUpper", TestStrToUpper},
565  {"StrTrimL", TestStrTrimL},
566  {"StrTrimR", TestStrTrimR},
567  {"StrTrim", TestStrTrim},
568  {"StrTrimmedLength",TestStrTrimmedLength},
569  {"StrUncomment", TestStrUncomment},
570  {"StrWhitespace", TestStrWhitespace},
571  {NULL, NULL}
572  };
573 
574  return TcuCreateSuite("String Utility", NULL, NULL, tests);
575 }
#define StrFree(x)
Definition: string_util.h:66
int TcuCreateSuite(const char *title, int(*init)(), int(*teardown)(), struct test_testdef *tests)
void StrWhitespace(char *line)
Definition: string_util.c:94
#define MemFree(ptr)
Definition: memory.h:48
char * StrStrdup(const char *string)
Definition: string_util.c:124
void StrStrncpy(char *dest, const char *src, size_t destlen)
Definition: string_util.c:176
void StrStrncat(char *dest, const char *src, size_t destlen)
Definition: string_util.c:191
void StrTrimR(char *text)
Definition: string_util.c:228
size_t StrToLower(char *text)
Definition: string_util.c:323
size_t StrReplaceChar(char *string, char search, char replace)
Definition: string_util.c:413
int TestStr(void)
void StrUncomment(char *line)
Definition: string_util.c:65
char * StrTrimL(char *text)
Definition: string_util.c:269
size_t StrReplaceCharN(char *string, size_t len, char search, char replace)
Definition: string_util.c:397
size_t StrTrimmedLength(const char *string)
Definition: string_util.c:442
char * StrTrim(char *text)
Definition: string_util.c:300
void * MemMalloc(size_t size)
Definition: memory.c:57
size_t StrToUpper(char *text)
Definition: string_util.c:353