moving stuff to custom git instance

This commit is contained in:
alessandro bason 2025-09-12 14:12:59 +02:00
parent a66e58193f
commit ccb992a44a
42 changed files with 4947 additions and 10390 deletions

View file

@ -1,370 +0,0 @@
#include "runner.h"
#include "../parsers.h"
#include "../arena.h"
#include <stdio.h>
// INI Parser Tests
UNIT_TEST(ini_parse_basic) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
strview_t ini_content = strv_init(
"[section1]\n"
"key1=value1\n"
"key2=value2\n"
"\n"
"[section2]\n"
"key3=value3\n"
"key4=value4\n"
);
ini_t ini = ini_parse_str(&arena, ini_content, NULL);
ASSERT(ini_is_valid(&ini));
// Test section1
initable_t *section1 = ini_get_table(&ini, strv_init("section1"));
ASSERT(section1 != NULL);
ASSERT(strv_equals(section1->name, strv_init("section1")));
// Test section1 values
inivalue_t *key1 = ini_get(section1, strv_init("key1"));
ASSERT(key1 != NULL);
ASSERT(strv_equals(key1->key, strv_init("key1")));
ASSERT(strv_equals(key1->value, strv_init("value1")));
inivalue_t *key2 = ini_get(section1, strv_init("key2"));
ASSERT(key2 != NULL);
ASSERT(strv_equals(key2->key, strv_init("key2")));
ASSERT(strv_equals(key2->value, strv_init("value2")));
// Test section2
initable_t *section2 = ini_get_table(&ini, strv_init("section2"));
ASSERT(section2 != NULL);
ASSERT(strv_equals(section2->name, strv_init("section2")));
// Test section2 values
inivalue_t *key3 = ini_get(section2, strv_init("key3"));
ASSERT(key3 != NULL);
ASSERT(strv_equals(key3->key, strv_init("key3")));
ASSERT(strv_equals(key3->value, strv_init("value3")));
inivalue_t *key4 = ini_get(section2, strv_init("key4"));
ASSERT(key4 != NULL);
ASSERT(strv_equals(key4->key, strv_init("key4")));
ASSERT(strv_equals(key4->value, strv_init("value4")));
arena_cleanup(&arena);
}
UNIT_TEST(ini_parse_with_options) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
strview_t ini_content = strv_init(
"[section1]\n"
"key1:value1\n"
"# This is a comment\n"
"key2:value2\n"
"\n"
"[section1]\n" // Duplicate section
"key3:value3\n"
);
iniopt_t options = {
.merge_duplicate_tables = true,
.merge_duplicate_keys = false,
.key_value_divider = ':',
.comment_vals = strv_init("#")
};
ini_t ini = ini_parse_str(&arena, ini_content, &options);
ASSERT(ini_is_valid(&ini));
// Test section1 (should be merged)
initable_t *section1 = ini_get_table(&ini, strv_init("section1"));
ASSERT(section1 != NULL);
// Check all keys exist in merged section
inivalue_t *key1 = ini_get(section1, strv_init("key1"));
ASSERT(key1 != NULL);
ASSERT(strv_equals(key1->value, strv_init("value1")));
inivalue_t *key2 = ini_get(section1, strv_init("key2"));
ASSERT(key2 != NULL);
ASSERT(strv_equals(key2->value, strv_init("value2")));
inivalue_t *key3 = ini_get(section1, strv_init("key3"));
ASSERT(key3 != NULL);
ASSERT(strv_equals(key3->value, strv_init("value3")));
arena_cleanup(&arena);
}
UNIT_TEST(ini_value_conversion) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
strview_t ini_content = strv_init(
"[values]\n"
"uint=42\n"
"int=-42\n"
"float=3.14\n"
"bool_true=true\n"
"bool_false=false\n"
"array=item1,item2,item3\n"
);
ini_t ini = ini_parse_str(&arena, ini_content, NULL);
initable_t *values = ini_get_table(&ini, strv_init("values"));
ASSERT(values != NULL);
// Test uint conversion
inivalue_t *uint_val = ini_get(values, strv_init("uint"));
ASSERT(uint_val != NULL);
ASSERT(ini_as_uint(uint_val) == 42);
// Test int conversion
inivalue_t *int_val = ini_get(values, strv_init("int"));
ASSERT(int_val != NULL);
ASSERT(ini_as_int(int_val) == -42);
// Test float conversion
inivalue_t *float_val = ini_get(values, strv_init("float"));
ASSERT(float_val != NULL);
ASSERT(ini_as_num(float_val) > 3.13 && ini_as_num(float_val) < 3.15);
// Test bool conversion
inivalue_t *bool_true = ini_get(values, strv_init("bool_true"));
ASSERT(bool_true != NULL);
ASSERT(ini_as_bool(bool_true) == true);
inivalue_t *bool_false = ini_get(values, strv_init("bool_false"));
ASSERT(bool_false != NULL);
ASSERT(ini_as_bool(bool_false) == false);
// Test array conversion
inivalue_t *array_val = ini_get(values, strv_init("array"));
ASSERT(array_val != NULL);
iniarray_t array = ini_as_arr(&arena, array_val, ',');
ASSERT(array.count == 3);
ASSERT(strv_equals(array.values[0], strv_init("item1")));
ASSERT(strv_equals(array.values[1], strv_init("item2")));
ASSERT(strv_equals(array.values[2], strv_init("item3")));
arena_cleanup(&arena);
}
// JSON Parser Tests
UNIT_TEST(json_parse_basic) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
strview_t json_content = strv_init(
"{\n"
" \"string\": \"value\",\n"
" \"number\": 42,\n"
" \"bool\": true,\n"
" \"null\": null,\n"
" \"array\": [1, 2, 3],\n"
" \"object\": {\n"
" \"nested\": \"nested_value\"\n"
" }\n"
"}"
);
json_t *root = json_parse_str(&arena, json_content, JSON_DEFAULT);
ASSERT(root != NULL);
ASSERT(root->type == JSON_OBJECT);
// Test string
json_t *string_node = json_get(root, strv_init("string"));
ASSERT(json_check(string_node, JSON_STRING));
ASSERT(strv_equals(string_node->string, strv_init("value")));
// Test number
json_t *number_node = json_get(root, strv_init("number"));
ASSERT(json_check(number_node, JSON_NUMBER));
ASSERT(number_node->number == 42);
// Test bool
json_t *bool_node = json_get(root, strv_init("bool"));
ASSERT(json_check(bool_node, JSON_BOOL));
ASSERT(bool_node->boolean == true);
// Test null
json_t *null_node = json_get(root, strv_init("null"));
ASSERT(json_check(null_node, JSON_NULL));
// Test array
json_t *array_node = json_get(root, strv_init("array"));
ASSERT(json_check(array_node, JSON_ARRAY));
// Test array contents
int count = 0;
int sum = 0;
json_for(item, array_node) {
ASSERT(json_check(item, JSON_NUMBER));
sum += (int)item->number;
count++;
}
ASSERT(count == 3);
ASSERT(sum == 6); // 1 + 2 + 3
// Test nested object
json_t *object_node = json_get(root, strv_init("object"));
ASSERT(json_check(object_node, JSON_OBJECT));
json_t *nested_node = json_get(object_node, strv_init("nested"));
ASSERT(json_check(nested_node, JSON_STRING));
ASSERT(strv_equals(nested_node->string, strv_init("nested_value")));
arena_cleanup(&arena);
}
UNIT_TEST(json_parse_with_options) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
// JSON with comments and trailing commas
strview_t json_content = strv_init(
"{\n"
" \"key1\": \"value1\",\n"
" // This is a comment\n"
" \"key2\": \"value2\",\n"
" \"array\": [\n"
" 1,\n"
" 2,\n"
" 3,\n" // Trailing comma
" ],\n" // Trailing comma
"}"
);
// Test with default flags (should allow comments and trailing commas)
json_t *root1 = json_parse_str(&arena, json_content, JSON_DEFAULT);
ASSERT(root1 != NULL);
ASSERT(json_get(root1, strv_init("key1")) != NULL);
ASSERT(json_get(root1, strv_init("key2")) != NULL);
// Test with NO_COMMENTS and NO_TRAILING_COMMAS flags
json_t *root2 = json_parse_str(&arena, json_content, JSON_NO_COMMENTS | JSON_NO_TRAILING_COMMAS);
// This should fail parsing due to the strict flags - but the behavior depends on implementation
// Some parsers might ignore the errors, others might return NULL
// We'll check both possibilities
if (root2 != NULL) {
// If parsing succeeded despite strict flags, ensure the content is correct
ASSERT(json_get(root2, strv_init("key1")) != NULL);
// key2 might be missing if comment handling failed
}
arena_cleanup(&arena);
}
// XML Parser Tests
UNIT_TEST(xml_parse_basic) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
strview_t xml_content = strv_init(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<root>\n"
" <item id=\"1\" type=\"book\">\n"
" <title>Test Title</title>\n"
" <author>Test Author</author>\n"
" </item>\n"
" <item id=\"2\" type=\"magazine\">\n"
" <title>Another Title</title>\n"
" </item>\n"
"</root>"
);
xml_t xml = xml_parse_str(&arena, xml_content);
ASSERT(xml.root != NULL);
ASSERT(strv_equals(xml.root->key, strv_init("root")));
// Find item tags
xmltag_t *item = xml_get_tag(xml.root, strv_init("item"), false);
ASSERT(item != NULL);
// Check attributes
strview_t id = xml_get_attribute(item, strv_init("id"));
ASSERT(strv_equals(id, strv_init("1")));
strview_t type = xml_get_attribute(item, strv_init("type"));
ASSERT(strv_equals(type, strv_init("book")));
// Check nested tags
xmltag_t *title = xml_get_tag(item, strv_init("title"), false);
ASSERT(title != NULL);
ASSERT(strv_equals(title->content, strv_init("Test Title")));
xmltag_t *author = xml_get_tag(item, strv_init("author"), false);
ASSERT(author != NULL);
ASSERT(strv_equals(author->content, strv_init("Test Author")));
// Check recursive tag finding
xmltag_t *title_recursive = xml_get_tag(xml.root, strv_init("title"), true);
ASSERT(title_recursive != NULL);
ASSERT(strv_equals(title_recursive->content, strv_init("Test Title")));
arena_cleanup(&arena);
}
// HTML Parser Tests
UNIT_TEST(html_parse_basic) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
strview_t html_content = strv_init(
"<!DOCTYPE html>\n"
"<html>\n"
"<head>\n"
" <title>Test Page</title>\n"
"</head>\n"
"<body>\n"
" <h1>Hello World</h1>\n"
" <p class=\"intro\">This is a test.</p>\n"
" <div id=\"content\">\n"
" <p>More content here.</p>\n"
" </div>\n"
"</body>\n"
"</html>"
);
html_t html = html_parse_str(&arena, html_content);
ASSERT(html.root != NULL);
ASSERT(str_equals(html.root->key, str_init(&arena, "html")));
// Find head and body
htmltag_t *head = html_get_tag(html.root, strv_init("head"), false);
ASSERT(head != NULL);
htmltag_t *body = html_get_tag(html.root, strv_init("body"), false);
ASSERT(body != NULL);
// Find title in head
htmltag_t *title = html_get_tag(head, strv_init("title"), false);
ASSERT(title != NULL);
ASSERT(strv_equals(title->content, strv_init("Test Page")));
// Find elements in body
htmltag_t *h1 = html_get_tag(body, strv_init("h1"), false);
ASSERT(h1 != NULL);
ASSERT(strv_equals(h1->content, strv_init("Hello World")));
// Find paragraph with class
htmltag_t *p = html_get_tag(body, strv_init("p"), false);
ASSERT(p != NULL);
strview_t p_class = html_get_attribute(p, strv_init("class"));
ASSERT(strv_equals(p_class, strv_init("intro")));
ASSERT(strv_equals(p->content, strv_init("This is a test.")));
// Find div by id
htmltag_t *div = html_get_tag(body, strv_init("div"), false);
ASSERT(div != NULL);
strview_t div_id = html_get_attribute(div, strv_init("id"));
ASSERT(strv_equals(div_id, strv_init("content")));
// Find nested paragraph using recursive search
htmltag_t *nested_p = html_get_tag(div, strv_init("p"), false);
ASSERT(nested_p != NULL);
ASSERT(strv_equals(nested_p->content, strv_init("More content here.")));
arena_cleanup(&arena);
}