tests/test_properties.c

changeset 928
d2d42cb1d59e
parent 924
3c90dfc35f06
child 929
192a440b99df
--- a/tests/test_properties.c	Sun Oct 13 15:19:12 2024 +0200
+++ b/tests/test_properties.c	Sun Oct 13 16:44:29 2024 +0200
@@ -27,8 +27,10 @@
  */
 
 #include "cx/test.h"
+#include "util_allocator.h"
 
 #include "cx/properties.h"
+#include "cx/hash_map.h"
 
 CX_TEST(test_cx_properties_init) {
     CxProperties prop;
@@ -89,7 +91,7 @@
 
     CxProperties prop;
     cxPropertiesInitDefault(&prop);
-    enum cx_properties_status result;
+    CxPropertiesStatus result;
     cxstring key;
     cxstring value;
     CX_TEST_DO {
@@ -155,7 +157,7 @@
 
     CxProperties prop;
     cxPropertiesInitDefault(&prop);
-    enum cx_properties_status result;
+    CxPropertiesStatus result;
     cxstring key;
     cxstring value;
 
@@ -178,7 +180,7 @@
 CX_TEST(test_cx_properties_next_part) {
     CxProperties prop;
     cxPropertiesInitDefault(&prop);
-    enum cx_properties_status result;
+    CxPropertiesStatus result;
     cxstring key;
     cxstring value;
     const char *str;
@@ -287,7 +289,7 @@
 CX_TEST(test_ucx_properties_next_long_lines) {
     CxProperties prop;
     cxPropertiesInitDefault(&prop);
-    enum cx_properties_status result;
+    CxPropertiesStatus result;
     cxstring key;
     cxstring value;
     
@@ -367,6 +369,139 @@
     free(long_value);
 }
 
+CX_TEST(test_cx_properties_load_string_to_map) {
+    CxTestingAllocator talloc;
+    cx_testing_allocator_init(&talloc);
+    CxAllocator *alloc = &talloc.base;
+    CX_TEST_DO {
+        const char *str = "key1 = value1\nkey2 = value2\n\n#comment\n\nkey3 = value3\n";
+
+        CxMap *map = cxHashMapCreateSimple(CX_STORE_POINTERS);
+        cxDefineAdvancedDestructor(map, cxFree, alloc);
+        CxProperties prop;
+        cxPropertiesInitDefault(&prop);
+        CxPropertiesSink sink = cxPropertiesMapSink(map);
+        sink.data = alloc; // use the testing allocator
+        CxPropertiesSource src = cxPropertiesCstrSource(str);
+        CxPropertiesStatus status = cxPropertiesLoad(&prop, sink, src);
+
+        CX_TEST_ASSERT(status == CX_PROPERTIES_NO_ERROR);
+        CX_TEST_ASSERT(cxMapSize(map) == 3);
+
+        char *v1 = cxMapGet(map, "key1");
+        char *v2 = cxMapGet(map, "key2");
+        char *v3 = cxMapGet(map, "key3");
+
+        CX_TEST_ASSERTM(v1, "value for key1 not found");
+        CX_TEST_ASSERTM(v2, "value for key2 not found");
+        CX_TEST_ASSERTM(v3, "value for key3 not found");
+
+        CX_TEST_ASSERT(!strcmp(v1, "value1"));
+        CX_TEST_ASSERT(!strcmp(v2, "value2"));
+        CX_TEST_ASSERT(!strcmp(v3, "value3"));
+
+        // second test
+        cxMapClear(map);
+
+        str = "\n#comment\n";
+        src = cxPropertiesCstrnSource(str, strlen(str));
+        status = cxPropertiesLoad(&prop, sink, src);
+
+        CX_TEST_ASSERT(status == CX_PROPERTIES_NO_DATA);
+        CX_TEST_ASSERT(cxMapSize(map) == 0);
+
+        str = "key1 = value1\nsyntax error line\n";
+        src = cxPropertiesStringSource(cx_str(str));
+        status = cxPropertiesLoad(&prop, sink, src);
+
+        CX_TEST_ASSERT(status == CX_PROPERTIES_INVALID_MISSING_DELIMITER);
+
+        // the successfully read k/v-pair is in the map, nevertheless
+        CX_TEST_ASSERT(cxMapSize(map) == 1);
+        char *v = cxMapGet(map, "key1");
+        CX_TEST_ASSERT(!strcmp(v, "value1"));
+
+        cxMapDestroy(map);
+        cxPropertiesDestroy(&prop);
+
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
+    }
+    cx_testing_allocator_destroy(&talloc);
+}
+
+CX_TEST(test_cx_properties_load_file_to_map) {
+    CxTestingAllocator talloc;
+    cx_testing_allocator_init(&talloc);
+    CxAllocator *alloc = &talloc.base;
+    CX_TEST_DO {
+        FILE *f = tmpfile();
+        CX_TEST_ASSERTM(f, "test file cannot be opened, test aborted");
+        fprintf(f, "# properties file\n\nkey1 = value1\nkey2 = value2\n");
+        fprintf(f, "\n\nkey3    = value3\n\n");
+
+        size_t key_len = 512;
+        char *long_key = (char *) malloc(key_len);
+        memset(long_key, 'k', 512);
+
+        size_t value_len = 2048;
+        char *long_value = (char *) malloc(value_len);
+        memset(long_value, 'v', 2048);
+
+        fwrite(long_key, 1, key_len, f);
+        fprintf(f, "    =    ");
+        fwrite(long_value, 1, value_len, f);
+        fprintf(f, "                         \n");
+
+        fprintf(f, "\n\n\n\nlast_key = property value\n");
+
+        fflush(f);
+        fseek(f, 0, SEEK_SET);
+
+        // preparation of test file complete
+
+        CxMap *map = cxHashMapCreateSimple(CX_STORE_POINTERS);
+        cxDefineAdvancedDestructor(map, cxFree, alloc);
+        CxProperties prop;
+        cxPropertiesInitDefault(&prop);
+        CxPropertiesSink sink = cxPropertiesMapSink(map);
+        sink.data = alloc; // use the testing allocator
+        CxPropertiesSource src = cxPropertiesFileSource(f, 512);
+        CxPropertiesStatus status = cxPropertiesLoad(&prop, sink, src);
+        fclose(f);
+
+        CX_TEST_ASSERT(status == CX_PROPERTIES_NO_ERROR);
+        CX_TEST_ASSERT(cxMapSize(map) == 5);
+
+        char *v1 = cxMapGet(map, "key1");
+        char *v2 = cxMapGet(map, cx_str("key2"));
+        char *v3 = cxMapGet(map, "key3");
+        char *lv = cxMapGet(map, cx_strn(long_key, key_len));
+        char *lk = cxMapGet(map, "last_key");
+
+        CX_TEST_ASSERTM(v1, "value for key1 not found");
+        CX_TEST_ASSERTM(v2, "value for key2 not found");
+        CX_TEST_ASSERTM(v3, "value for key3 not found");
+        CX_TEST_ASSERTM(lv, "value for long key not found");
+        CX_TEST_ASSERTM(lk, "value for last_key not found");
+
+        CX_TEST_ASSERT(!strcmp(v1, "value1"));
+        CX_TEST_ASSERT(!strcmp(v2, "value2"));
+        CX_TEST_ASSERT(!strcmp(v3, "value3"));
+        cxstring expected = cx_strn(long_value, value_len);
+        cxstring actual = cx_str(lv);
+        CX_TEST_ASSERT(!cx_strcmp(expected, actual));
+        CX_TEST_ASSERT(!strcmp(lk, "property value"));
+
+        free(long_key);
+        free(long_value);
+        cxMapDestroy(map);
+        cxPropertiesDestroy(&prop);
+
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
+    }
+    cx_testing_allocator_destroy(&talloc);
+}
+
 CxTestSuite *cx_test_suite_properties(void) {
     CxTestSuite *suite = cx_test_suite_new("properties");
 
@@ -375,6 +510,8 @@
     cx_test_register(suite, test_cx_properties_next_multi);
     cx_test_register(suite, test_cx_properties_next_part);
     cx_test_register(suite, test_ucx_properties_next_long_lines);
+    cx_test_register(suite, test_cx_properties_load_string_to_map);
+    cx_test_register(suite, test_cx_properties_load_file_to_map);
 
     return suite;
 }

mercurial