#include "runner.h" #include "../net.h" #include "../arena.h" #include // Initialization Tests UNIT_TEST(net_init_cleanup) { net_init(); // Simple test to make sure initialization succeeds ASSERT(net_get_last_error() == 0); net_cleanup(); } // HTTP Method/Status Tests UNIT_TEST(http_method_strings) { ASSERT(strcmp(http_get_method_string(HTTP_GET), "GET") == 0); ASSERT(strcmp(http_get_method_string(HTTP_POST), "POST") == 0); ASSERT(strcmp(http_get_method_string(HTTP_HEAD), "HEAD") == 0); ASSERT(strcmp(http_get_method_string(HTTP_PUT), "PUT") == 0); ASSERT(strcmp(http_get_method_string(HTTP_DELETE), "DELETE") == 0); } UNIT_TEST(http_status_strings) { ASSERT(strcmp(http_get_status_string(200), "OK") == 0); ASSERT(strcmp(http_get_status_string(404), "NOT FOUND") == 0); ASSERT(strcmp(http_get_status_string(500), "INTERNAL SERVER ERROR") == 0); } // HTTP Headers Tests UNIT_TEST(http_headers) { arena_t arena = arena_make(ARENA_MALLOC, KB(4)); // Parse headers strview_t header_str = strv_init("Content-Type: application/json\r\nUser-Agent: Colla\r\n"); http_header_t *headers = http_parse_headers(&arena, header_str); // Check headers were parsed correctly ASSERT(headers != NULL); // Headers are parsed in reverse order ASSERT(strv_equals(headers->key, strv_init("User-Agent"))); ASSERT(strv_equals(headers->value, strv_init("Colla"))); ASSERT(strv_equals(headers->next->key, strv_init("Content-Type"))); ASSERT(strv_equals(headers->next->value, strv_init("application/json"))); // Test header operations ASSERT(http_has_header(headers, strv_init("Content-Type"))); ASSERT(!http_has_header(headers, strv_init("Accept"))); strview_t content_type = http_get_header(headers, strv_init("Content-Type")); ASSERT(strv_equals(content_type, strv_init("application/json"))); // Don't try to free headers as they're allocated in the arena arena_cleanup(&arena); } // HTTP Request/Response Parsing Tests UNIT_TEST(http_request_parsing) { arena_t arena = arena_make(ARENA_MALLOC, KB(4)); strview_t req_str = strv_init( "GET /index.html HTTP/1.1\r\n" "Host: example.com\r\n" "User-Agent: Colla\r\n" "\r\n" ); http_req_t req = http_parse_req(&arena, req_str); ASSERT(req.method == HTTP_GET); ASSERT(req.version.major == 1); ASSERT(req.version.minor == 1); ASSERT(strv_equals(req.url, strv("index.html"))); ASSERT(http_has_header(req.headers, strv_init("Host"))); ASSERT(strv_equals(http_get_header(req.headers, strv_init("Host")), strv_init("example.com"))); // Convert back to string str_t req_out = http_req_to_str(&arena, &req); ASSERT(!str_is_empty(req_out)); arena_cleanup(&arena); } UNIT_TEST(http_response_parsing) { arena_t arena = arena_make(ARENA_MALLOC, KB(4)); strview_t res_str = strv_init( "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "Content-Length: 13\r\n" "\r\n" "Hello, World!" ); http_res_t res = http_parse_res(&arena, res_str); ASSERT(res.status_code == 200); ASSERT(res.version.major == 1); ASSERT(res.version.minor == 1); ASSERT(strv_equals(res.body, strv_init("Hello, World!"))); ASSERT(http_has_header(res.headers, strv_init("Content-Type"))); ASSERT(strv_equals(http_get_header(res.headers, strv_init("Content-Type")), strv_init("text/html"))); // Convert back to string str_t res_out = http_res_to_str(&arena, &res); ASSERT(!str_is_empty(res_out)); arena_cleanup(&arena); } // URL Encoding/Decoding Tests UNIT_TEST(http_url_encoding) { arena_t arena = arena_make(ARENA_MALLOC, KB(4)); strview_t original = strv_init("hello world & special chars: ?=&/"); str_t encoded = http_make_url_safe(&arena, original); str_t decoded = http_decode_url_safe(&arena, strv_init_str(encoded)); ASSERT(!str_is_empty(encoded)); ASSERT(str_equals(decoded, str_init(&arena, "hello world & special chars: ?=&/"))); arena_cleanup(&arena); } UNIT_TEST(http_url_splitting) { strview_t url = strv_init("http://example.com/path?query=value"); http_url_t split = http_split_url(url); ASSERT(strv_equals(split.host, strv_init("example.com"))); ASSERT(strv_equals(split.uri, strv_init("/path?query=value"))); } // HTTP Request Tests // Note: These tests would actually make network requests, so we should mock them // for real unit tests. Here we'll just test the setup part. UNIT_TEST(http_request_setup) { arena_t arena = arena_make(ARENA_MALLOC, KB(4)); // Prepare headers http_header_t headers[2] = { { .key = strv_init("Content-Type"), .value = strv_init("application/json"), .next = &headers[1] }, { .key = strv_init("User-Agent"), .value = strv_init("Colla Test"), .next = NULL } }; // Setup request descriptor http_request_desc_t desc = { .arena = &arena, .url = strv_init("http://example.com"), .version = { .major = 1, .minor = 1 }, .request_type = HTTP_GET, .headers = headers, .header_count = 2, .body = strv_init("") }; // We don't actually make the request, just verify the setup is correct ASSERT(desc.arena == &arena); ASSERT(strv_equals(desc.url, strv_init("http://example.com"))); ASSERT(desc.request_type == HTTP_GET); ASSERT(desc.headers == headers); ASSERT(desc.header_count == 2); arena_cleanup(&arena); } // Socket Tests UNIT_TEST(socket_basic) { net_init(); // Open a socket socket_t sock = sk_open(SOCK_TCP); ASSERT(sk_is_valid(sock)); // Close the socket ASSERT(sk_close(sock)); net_cleanup(); } // SHA1 Tests UNIT_TEST(sha1_hash) { arena_t arena = arena_make(ARENA_MALLOC, KB(4)); sha1_t ctx = sha1_init(); const char *data = "Hello, World!"; str_t hash = sha1_str(&arena, &ctx, data, strlen(data)); // The SHA1 hash for "Hello, World!" is known // But we'll just verify it's not empty and has the expected format (40 hex chars) ASSERT(!str_is_empty(hash)); ASSERT(hash.len == 40); arena_cleanup(&arena); } // Base64 Tests UNIT_TEST(base64_encoding) { arena_t arena = arena_make(ARENA_MALLOC, KB(4)); const char *original = "Hello, World!"; buffer_t input = { (u8*)original, strlen(original) }; // Encode buffer_t encoded = base64_encode(&arena, input); ASSERT(encoded.data != NULL); ASSERT(encoded.len > 0); // Decode buffer_t decoded = base64_decode(&arena, encoded); ASSERT(decoded.data != NULL); ASSERT(decoded.len == input.len); ASSERT(memcmp(decoded.data, input.data, input.len) == 0); arena_cleanup(&arena); } // WebSocket Tests UNIT_TEST(websocket_encoding) { arena_t arena = arena_make(ARENA_MALLOC, KB(4)); strview_t message = strv_init("Hello, WebSocket!"); // Encode message to WebSocket format buffer_t encoded = websocket_encode(&arena, message); ASSERT(encoded.data != NULL); ASSERT(encoded.len > 0); // Decode WebSocket message str_t decoded = websocket_decode(&arena, encoded); ASSERT(!str_is_empty(decoded)); ASSERT(str_equals(decoded, str_init(&arena, "Hello, WebSocket!"))); arena_cleanup(&arena); }