aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--src/sds.c125
-rw-r--r--src/sds.h3
-rw-r--r--src/test.c244
-rw-r--r--src/testhelp.h57
-rw-r--r--src/twbctf.c49
-rw-r--r--src/twbctf.h14
7 files changed, 310 insertions, 188 deletions
diff --git a/Makefile b/Makefile
index cff5cac..7e5f5b6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
-CFLAGS = -Weverything -std=c11
+CFLAGS = -Weverything -std=c11 -g
CC = clang
-SOURCES = src/test.c src/sds.c
-HEADERS = src/test.h src/sds.c
+SOURCES = src/twbctf.c src/sds.c
+HEADERS = src/twbctf.h src/sds.c
all: sds-test
sds-test: $(SOURCES) $(HEADERS)
diff --git a/src/sds.c b/src/sds.c
index 5306f1f..74d2c44 100644
--- a/src/sds.c
+++ b/src/sds.c
@@ -11,9 +11,6 @@
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -782,126 +779,4 @@ sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) {
return join;
}
-#ifdef SDS_TEST_MAIN
-#include <stdio.h>
-#include "testhelp.h"
-int main(void) {
- {
- struct sdshdr *sh;
- sds x = sdsnew("foo"), y;
-
- test_cond("Create a string and obtain the length",
- sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0)
-
- sdsfree(x);
- x = sdsnewlen("foo",2);
- test_cond("Create a string with specified length",
- sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0)
-
- x = sdscat(x,"bar");
- test_cond("Strings concatenation",
- sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0);
-
- x = sdscpy(x,"a");
- test_cond("sdscpy() against an originally longer string",
- sdslen(x) == 1 && memcmp(x,"a\0",2) == 0)
-
- x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk");
- test_cond("sdscpy() against an originally shorter string",
- sdslen(x) == 33 &&
- memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0)
-
- sdsfree(x);
- x = sdscatprintf(sdsempty(),"%d",123);
- test_cond("sdscatprintf() seems working in the base case",
- sdslen(x) == 3 && memcmp(x,"123\0",4) ==0)
-
- sdsfree(x);
- x = sdsnew("xxciaoyyy");
- sdstrim(x,"xy");
- test_cond("sdstrim() correctly trims characters",
- sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0)
-
- y = sdsdup(x);
- sdsrange(y,1,1);
- test_cond("sdsrange(...,1,1)",
- sdslen(y) == 1 && memcmp(y,"i\0",2) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,1,-1);
- test_cond("sdsrange(...,1,-1)",
- sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,-2,-1);
- test_cond("sdsrange(...,-2,-1)",
- sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,2,1);
- test_cond("sdsrange(...,2,1)",
- sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,1,100);
- test_cond("sdsrange(...,1,100)",
- sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,100,100);
- test_cond("sdsrange(...,100,100)",
- sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
-
- sdsfree(y);
- sdsfree(x);
- x = sdsnew("foo");
- y = sdsnew("foa");
- test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0)
-
- sdsfree(y);
- sdsfree(x);
- x = sdsnew("bar");
- y = sdsnew("bar");
- test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0)
-
- sdsfree(y);
- sdsfree(x);
- x = sdsnew("aar");
- y = sdsnew("bar");
- test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0)
-
- sdsfree(y);
- sdsfree(x);
- x = sdsnewlen("\a\n\0foo\r",7);
- y = sdscatrepr(sdsempty(),x,sdslen(x));
- test_cond("sdscatrepr(...data...)",
- memcmp(y,"\"\\a\\n\\x00foo\\r\"",15) == 0)
-
- {
- int oldfree;
-
- sdsfree(x);
- x = sdsnew("0");
- sh = (void*) (x-(sizeof(struct sdshdr)));
- test_cond("sdsnew() free/len buffers", sh->len == 1 && sh->free == 0);
- x = sdsMakeRoomFor(x,1);
- sh = (void*) (x-(sizeof(struct sdshdr)));
- test_cond("sdsMakeRoomFor()", sh->len == 1 && sh->free > 0);
- oldfree = sh->free;
- x[1] = '1';
- sdsIncrLen(x,1);
- test_cond("sdsIncrLen() -- content", x[0] == '0' && x[1] == '1');
- test_cond("sdsIncrLen() -- len", sh->len == 2);
- test_cond("sdsIncrLen() -- free", sh->free == oldfree-1);
- }
- }
- test_report()
- return 0;
-}
-#endif
diff --git a/src/sds.h b/src/sds.h
index ab6fc9c..b4243f0 100644
--- a/src/sds.h
+++ b/src/sds.h
@@ -11,9 +11,6 @@
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/src/test.c b/src/test.c
new file mode 100644
index 0000000..32d12a3
--- /dev/null
+++ b/src/test.c
@@ -0,0 +1,244 @@
+#include <stdbool.h>
+#include <string.h>
+
+#include "sds.h"
+#include "twbctf.h"
+
+bool check_string_length (void);
+bool create_with_length (void);
+bool string_concat (void);
+bool sdscpy_against_longer_str (void);
+bool sdscpy_against_shorter_str (void);
+bool sdscatprintf_base_case (void);
+bool sdstrim_trims_correctly (void);
+bool sdsrange_one_one (void);
+bool sdsrange_one_none (void);
+bool sdsrange_ntwo_none (void);
+bool sdsrange_two_one (void);
+bool sdsrange_one_hund (void);
+bool sdsrange_hund_hund (void);
+bool sdscmp_foo_foa (void);
+bool sdscmp_aar_bar (void);
+bool sdscmp_bar_bar (void);
+bool sdscatrepr_test (void);
+bool sdsnew_check_free_len (void);
+bool sdsMakeRoomFor_test (void);
+bool sdsIncrLen_content (void);
+bool sdsIncrLen_len (void);
+bool sdsIncrLen_free (void);
+
+struct test test_list [] = {
+ { "create a string and obtain the length", check_string_length },
+ { "create a string with specified length", create_with_length },
+ { "string concatenation", string_concat },
+ { "sdscpy() against a longer string", sdscpy_against_longer_str },
+ { "sdscpy() against a shorter string", sdscpy_against_shorter_str },
+ { "basic sdscatprintf() usecase", sdscatprintf_base_case },
+ { "sdstrim() trims correctly", sdstrim_trims_correctly },
+ { "sdsrange(..., 1, 1)", sdsrange_one_one },
+ { "sdsrange(..., 1, -1)", sdsrange_one_none },
+ { "sdsrange(..., -2, -1)", sdsrange_ntwo_none },
+ { "sdsrange(..., 2, 1)", sdsrange_two_one },
+ { "sdsrange(..., 1, 100)", sdsrange_one_hund },
+ { "sdsrange(..., 100, 100)", sdsrange_hund_hund },
+ { "sdscmp(foo, foa)", sdscmp_foo_foa },
+ { "sdscmp(aar, bar)", sdscmp_aar_bar },
+ { "sdscmp(bar, bar)", sdscmp_bar_bar },
+ { "sdscatrepr(...data...)", sdscatrepr_test },
+ { "sdsnew() free/len buffers", sdsnew_check_free_len },
+ { "sdsMakeRoomFor()", sdsMakeRoomFor_test },
+ { "content after sdsIncrLen()", sdsIncrLen_content },
+ { "len after sdsIncrLen()", sdsIncrLen_len },
+ { "free after sdsIncrLen()", sdsIncrLen_free },
+};
+
+static inline void sdsfrees(sds *string) { if (*string) sdsfree(*string); }
+#define _sds_cleanup_ __attribute__((cleanup(sdsfrees)))
+
+bool
+check_string_length(void) {
+ _sds_cleanup_ sds x = sdsnew("foo");
+
+ return (sdslen(x) == 3 && memcmp(x, "foo\0", 4) == 0);
+}
+
+bool
+create_with_length(void) {
+ _sds_cleanup_ sds x = sdsnewlen("foo", 2);
+
+ return (sdslen(x) == 2 && memcmp(x, "fo\0", 3) == 0);
+}
+
+bool
+string_concat(void) {
+ _sds_cleanup_ sds x = sdsnewlen("foo", 2);
+ x = sdscat(x, "bar");
+
+ return (sdslen(x) == 5 && memcmp(x, "fobar\0", 6) == 0);
+}
+
+bool
+sdscpy_against_longer_str(void) {
+ _sds_cleanup_ sds x = sdsnew("foo");
+ x = sdscpy(x, "a");
+
+ return (sdslen(x) == 1 && memcmp(x, "a\0", 2) == 0);
+}
+
+bool
+sdscpy_against_shorter_str(void) {
+ _sds_cleanup_ sds x = sdsnewlen("foo",2);
+ x = sdscpy(x, "xxxxyyyyzzzz");
+
+ return (sdslen(x) == 12 && memcmp(x, "xxxxyyyyzzzz\0", 12) == 0);
+}
+
+bool
+sdscatprintf_base_case(void) {
+ _sds_cleanup_ sds x = sdscatprintf(sdsempty(), "%d", 123);
+
+ return (sdslen(x) == 3 && memcmp(x, "123\0", 4) == 0);
+}
+
+bool
+sdstrim_trims_correctly(void) {
+ _sds_cleanup_ sds x = sdsnew("xxciaoyy");
+ sdstrim(x, "xy");
+
+ return (sdslen(x) == 4 && memcmp(x, "ciao\0", 5) == 0);
+}
+
+bool
+sdsrange_one_one (void) {
+ _sds_cleanup_ sds x = sdsnew("ciao");
+ _sds_cleanup_ sds y = sdsdup(x);
+ sdsrange(y, 1, 1);
+
+ return (sdslen(y) == 1 && memcmp(y, "i\0", 2) == 0);
+}
+
+bool
+sdsrange_one_none (void) {
+ _sds_cleanup_ sds x = sdsnew("ciao");
+ _sds_cleanup_ sds y = sdsdup(x);
+ sdsrange(y, 1, -1);
+
+ return (sdslen(y) == 3 && memcmp(y, "iao\0", 4) == 0);
+}
+
+bool
+sdsrange_ntwo_none (void) {
+ _sds_cleanup_ sds x = sdsnew("ciao");
+ _sds_cleanup_ sds y = sdsdup(x);
+ sdsrange(y, -2, -1);
+
+ return (sdslen(y) == 2 && memcmp(y, "ao\0", 3) == 0);
+}
+
+bool
+sdsrange_two_one (void) {
+ _sds_cleanup_ sds x = sdsnew("ciao");
+ _sds_cleanup_ sds y = sdsdup(x);
+ sdsrange(y, 2, 1);
+
+ return (sdslen(y) == 0 && memcmp(y, "\0", 1) == 0);
+}
+
+bool
+sdsrange_one_hund (void) {
+ _sds_cleanup_ sds x = sdsnew("ciao");
+ _sds_cleanup_ sds y = sdsdup(x);
+ sdsrange(y, 1, 100);
+
+ return (sdslen(y) == 3 && memcmp(y, "iao\0", 4) == 0);
+}
+
+bool
+sdsrange_hund_hund (void) {
+ _sds_cleanup_ sds x = sdsnew("ciao");
+ _sds_cleanup_ sds y = sdsdup(x);
+ sdsrange(y, 100, 100);
+
+ return (sdslen(y) == 0 && memcmp(y, "\0", 1) == 0);
+}
+
+bool
+sdscmp_foo_foa (void) {
+ _sds_cleanup_ sds x = sdsnew("foo");
+ _sds_cleanup_ sds y = sdsnew("foa");
+
+ return (sdscmp(x, y) > 0);
+}
+
+bool
+sdscmp_aar_bar (void) {
+ _sds_cleanup_ sds x = sdsnew("aar");
+ _sds_cleanup_ sds y = sdsnew("bar");
+
+ return (sdscmp(x, y) < 0);
+}
+
+bool
+sdscmp_bar_bar (void) {
+ _sds_cleanup_ sds x = sdsnew("bar");
+ _sds_cleanup_ sds y = sdsnew("bar");
+
+ return (sdscmp(x, y) == 0);
+}
+
+bool
+sdscatrepr_test (void) {
+ _sds_cleanup_ sds x = sdsnewlen("\a\n\0foo\r", 7);
+ _sds_cleanup_ sds y = sdscatrepr(sdsempty(), x, sdslen(x));
+ return (memcmp(y, "\"\\a\\n\\x00foo\\r\"", 15) == 0);
+}
+
+bool
+sdsnew_check_free_len (void) {
+ _sds_cleanup_ sds x = sdsnew("0");
+ struct sdshdr *sh = (void*) (x-(sizeof(struct sdshdr)));
+
+ return (sh->len == 1 && sh->free == 0);
+}
+
+bool
+sdsMakeRoomFor_test (void) {
+ _sds_cleanup_ sds x = sdsnew("0");
+ x = sdsMakeRoomFor(x, 1);
+ struct sdshdr *sh = (void*) (x-(sizeof(struct sdshdr)));
+
+ return (sh->len == 1 && sh->free > 0);
+}
+
+bool
+sdsIncrLen_content (void) {
+ _sds_cleanup_ sds x = sdsnew("0");
+ x = sdsMakeRoomFor(x, 1);
+ x[1] = '1';
+ sdsIncrLen(x, 1);
+
+ return (x[0] == '0' && x[1] == '1');
+}
+
+bool
+sdsIncrLen_len (void) {
+ _sds_cleanup_ sds x = sdsnew("0");
+ x = sdsMakeRoomFor(x, 1);
+ struct sdshdr *sh = (void*) (x-(sizeof(struct sdshdr)));
+ x[1] = '1';
+ sdsIncrLen(x, 1);
+
+ return (sh->len == 2);
+}
+
+bool
+sdsIncrLen_free (void) {
+ _sds_cleanup_ sds x = sdsnew("0");
+ x = sdsMakeRoomFor(x, 1);
+ struct sdshdr *sh = (void*) (x-(sizeof(struct sdshdr)));
+ int oldfree = sh->free;
+ x[1] = '1';
+ sdsIncrLen(x, 1);
+
+ return (sh->free == oldfree-1);
+}
diff --git a/src/testhelp.h b/src/testhelp.h
deleted file mode 100644
index 4503340..0000000
--- a/src/testhelp.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* This is a really minimal testing framework for C.
- *
- * Example:
- *
- * test_cond("Check if 1 == 1", 1==1)
- * test_cond("Check if 5 > 10", 5 > 10)
- * test_report()
- *
- * ----------------------------------------------------------------------------
- *
- * Copyright (c) 2010-2012, Salvatore Sanfilippo <antirez at gmail dot com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __TESTHELP_H
-#define __TESTHELP_H
-
-int __failed_tests = 0;
-int __test_num = 0;
-#define test_cond(descr,_c) do { \
- __test_num++; printf("%d - %s: ", __test_num, descr); \
- if(_c) printf("PASSED\n"); else {printf("FAILED\n"); __failed_tests++;} \
-} while(0);
-#define test_report() do { \
- printf("%d tests, %d passed, %d failed\n", __test_num, \
- __test_num-__failed_tests, __failed_tests); \
- if (__failed_tests) { \
- printf("=== WARNING === We have failed tests here...\n"); \
- exit(1); \
- } \
-} while(0);
-
-#endif
diff --git a/src/twbctf.c b/src/twbctf.c
new file mode 100644
index 0000000..32d2f9e
--- /dev/null
+++ b/src/twbctf.c
@@ -0,0 +1,49 @@
+/*******************************************************************\
+ * A small, C test framework *
+ * Copyright (C) 2013-2014, Sam Stuewe *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License *
+ * as published by the Free Software Foundation; either version 2 *
+ * of the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301, USA. *
+\*********************************************************************/
+
+// Libraries //
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "twbctf.h"
+#include "test.c"
+
+// Forward Declarations //
+#define TEST_COUNT ((sizeof test_list)/(sizeof (struct test)))
+
+// Run Suite //
+signed
+main (void) {
+ int print_width = 0;
+ for (int i = 0; i < TEST_COUNT; i++) {
+ if (strlen(test_list[i].desc) > print_width) {
+ print_width = strlen(test_list[i].desc);
+ }
+ }
+
+ for (size_t i = 0; i < TEST_COUNT; i++) {
+ printf("Testing %-*s\t\t[ PEND ]\r", print_width, test_list[i].desc);
+ char * result = (test_list[i].func() ? "\x1b[32mPASS" : "\x1b[31mFAIL");
+ printf("Testing %-*s\t\t[ %s \x1b[0m]\n", print_width, test_list[i].desc, result);
+ }
+
+ return 0;
+}
diff --git a/src/twbctf.h b/src/twbctf.h
new file mode 100644
index 0000000..c0789cc
--- /dev/null
+++ b/src/twbctf.h
@@ -0,0 +1,14 @@
+#ifndef TWBCTF_H
+#define TWBCTF_H
+
+// Libraries //
+#include <stdbool.h>
+
+typedef bool (* test_p) (void);
+
+struct test {
+ char * desc;
+ test_p func;
+};
+
+#endif