diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | src/sds.c | 125 | ||||
-rw-r--r-- | src/sds.h | 3 | ||||
-rw-r--r-- | src/test.c | 244 | ||||
-rw-r--r-- | src/testhelp.h | 57 | ||||
-rw-r--r-- | src/twbctf.c | 49 | ||||
-rw-r--r-- | src/twbctf.h | 14 |
7 files changed, 310 insertions, 188 deletions
@@ -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) @@ -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 @@ -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 |