--- a/tests/test_properties.c Fri Dec 20 15:00:05 2024 +0100 +++ b/tests/test_properties.c Fri Dec 20 15:00:31 2024 +0100 @@ -41,9 +41,8 @@ CX_TEST_ASSERT(prop.config.comment1 == '#'); CX_TEST_ASSERT(prop.config.comment2 == 0); CX_TEST_ASSERT(prop.config.comment3 == 0); - CX_TEST_ASSERT(prop.flags == 0); - CX_TEST_ASSERT(prop.text == NULL); - CX_TEST_ASSERT(prop.buf == NULL); + CX_TEST_ASSERT(prop.input.space == NULL); + CX_TEST_ASSERT(prop.buffer.space == NULL); cxPropertiesDestroy(&prop); } @@ -97,9 +96,9 @@ CX_TEST_DO { for (int i = 0; i < 10; i++) { cxPropertiesFill(&prop, tests[i]); - CX_TEST_ASSERT(prop.text == tests[i]); - CX_TEST_ASSERT(prop.text_size == strlen(tests[i])); - CX_TEST_ASSERT(prop.text_pos == 0); + CX_TEST_ASSERT(prop.input.space == tests[i]); + CX_TEST_ASSERT(prop.input.size == strlen(tests[i])); + CX_TEST_ASSERT(prop.input.pos == 0); result = cxPropertiesNext(&prop, &key, &value); cxstring k = cx_str(keys[i]); @@ -203,35 +202,35 @@ CX_TEST_DO { str = ""; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA); str = " \n"; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA); str = "name"; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA); str = " "; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA); // call fill twice in a row str = "= "; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); str = "value"; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA); str = "\n"; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR); CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("name"))); @@ -239,17 +238,17 @@ // second round str = "#comment\n"; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA); str = "#comment\nname2 = "; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA); str = "value2\na = b\n"; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR); CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("name2"))); @@ -261,17 +260,17 @@ CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("b"))); str = "# comment\n#\n#\ntests = "; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA); str = "test1 "; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA); str = "test2 test3 test4\n"; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR); CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("tests"))); @@ -279,22 +278,22 @@ // test if cxPropertiesNext finds a name/value after a comment str = "# just a comment"; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA); str = " in 3"; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA); str = " parts\nx = 1\n"; - cxPropertiesFill(&prop, str); + CX_TEST_ASSERT(0 == cxPropertiesFill(&prop, str)); result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR); CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("x"))); CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("1"))); - + // finally we are done result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA); @@ -308,7 +307,7 @@ CxPropertiesStatus result; cxstring key; cxstring value; - + size_t key_len = 512; char *long_key = (char*)malloc(key_len); memset(long_key, 'a', 70); @@ -371,14 +370,13 @@ result = cxPropertiesNext(&prop, &key, &value); CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA); - CX_TEST_ASSERT(prop.buf != NULL); - CX_TEST_ASSERT(prop.buf_capacity > 0); - CX_TEST_ASSERT(prop.buf_size == 0); + CX_TEST_ASSERT(prop.buffer.capacity > 0); + CX_TEST_ASSERT(cxBufferEof(&prop.buffer)); + CX_TEST_ASSERT(cxBufferEof(&prop.input)); cxPropertiesDestroy(&prop); - - CX_TEST_ASSERT(prop.buf == NULL); - CX_TEST_ASSERT(prop.buf_capacity == 0); - CX_TEST_ASSERT(prop.buf_size == 0); + CX_TEST_ASSERT(prop.buffer.capacity == 0); + CX_TEST_ASSERT(prop.buffer.size == 0); + CX_TEST_ASSERT(prop.buffer.pos == 0); } free(long_key); @@ -521,6 +519,105 @@ cx_testing_allocator_destroy(&talloc); } +CX_TEST(test_properties_multiple_fill) { + const char *props1 = "key1 = value1\n"; + const char *props2 = "key2 = value2\n"; + const char *props3 = "key3 = value3\n"; + + CxProperties prop; + cxPropertiesInitDefault(&prop); + CxPropertiesStatus result; + cxstring key; + cxstring value; + CX_TEST_DO { + cxPropertiesFill(&prop, props1); + cxPropertiesFill(&prop, props2); + cxPropertiesFill(&prop, props3); + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR); + CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("key1"))); + CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("value1"))); + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR); + CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("key2"))); + CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("value2"))); + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR); + CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("key3"))); + CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("value3"))); + + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA); + } + cxPropertiesDestroy(&prop); +} + +CX_TEST(test_properties_use_stack) { + const char *props1 = "key1 = val"; + const char *props2 = "ue1\nkey2 = value2"; + const char *props3 = "\nkey3 = value3\n"; + char stackmem[16]; + + CxProperties prop; + cxPropertiesInitDefault(&prop); + cxPropertiesUseStack(&prop, stackmem, 16); + CxPropertiesStatus result; + cxstring key; + cxstring value; + CX_TEST_DO { + cxPropertiesFill(&prop, props1); + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA); + cxPropertiesFill(&prop, props2); + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR); + CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("key1"))); + CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("value1"))); + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_INCOMPLETE_DATA); + cxPropertiesFill(&prop, props3); + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR); + CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("key2"))); + CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("value2"))); + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR); + CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("key3"))); + CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("value3"))); + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_NO_DATA); + } + cxPropertiesDestroy(&prop); +} + +CX_TEST(test_properties_empty_key) { + const char *fail1 = "= val\n"; + const char *fail2 = " = val\n"; + const char *good = " key = val\n"; + + CxProperties prop; + CxPropertiesStatus result; + cxstring key; + cxstring value; + CX_TEST_DO { + cxPropertiesInitDefault(&prop); + cxPropertiesFill(&prop, fail1); + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_INVALID_EMPTY_KEY); + cxPropertiesReset(&prop); + cxPropertiesFill(&prop, fail2); + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_INVALID_EMPTY_KEY); + cxPropertiesReset(&prop); + cxPropertiesFill(&prop, good); + result = cxPropertiesNext(&prop, &key, &value); + CX_TEST_ASSERT(result == CX_PROPERTIES_NO_ERROR); + CX_TEST_ASSERT(0 == cx_strcmp(key, cx_str("key"))); + CX_TEST_ASSERT(0 == cx_strcmp(value, cx_str("val"))); + cxPropertiesDestroy(&prop); + } +} + CxTestSuite *cx_test_suite_properties(void) { CxTestSuite *suite = cx_test_suite_new("properties"); @@ -531,6 +628,9 @@ cx_test_register(suite, test_properties_next_long_lines); cx_test_register(suite, test_properties_load_string_to_map); cx_test_register(suite, test_properties_load_file_to_map); + cx_test_register(suite, test_properties_multiple_fill); + cx_test_register(suite, test_properties_use_stack); + cx_test_register(suite, test_properties_empty_key); return suite; }