「‍」 Lingenic

test

(⤓.cpp ◇.cpp); γ ≜ [2026-01-27T082245.651, 2026-01-27T082245.651] ∧ |γ| = 1

// HSV Parser Tests (C++)

#include <iostream>
#include <string>
#include <cstdlib>
#include "hsv.hpp"

using namespace hsv;

int passed = 0;
int failed = 0;

void assert_true(bool condition, const std::string& name) {
    if (condition) {
        std::cout << "" << name << "\n";
        passed++;
    } else {
        std::cout << "" << name << "\n";
        failed++;
    }
}

void assert_eq(const std::string& got, const std::string& expected, const std::string& name) {
    assert_true(got == expected, name + " (got: \"" + got + "\")");
}

void assert_eq(size_t got, size_t expected, const std::string& name) {
    assert_true(got == expected, name);
}

void test_basic() {
    std::string input = std::string() + STX + "name" + US + "Alice" + RS + "age" + US + "30" + ETX;
    auto doc = parse(input);

    assert_eq(doc.records.size(), 1u, "Basic: 1 record");
    assert_eq(get_string(doc.records[0], "name"), "Alice", "Basic: name=Alice");
    assert_eq(get_string(doc.records[0], "age"), "30", "Basic: age=30");
}

void test_multiple_records() {
    std::string input = std::string() + STX + "name" + US + "Alice" + FS + "name" + US + "Bob" + ETX;
    auto doc = parse(input);

    assert_eq(doc.records.size(), 2u, "Multiple records: 2 records");
}

void test_array_values() {
    std::string input = std::string() + STX + "tags" + US + "a" + GS + "b" + GS + "c" + ETX;
    auto doc = parse(input);

    assert_eq(doc.records.size(), 1u, "Array: 1 record");
    assert_true(doc.records[0].at("tags").is_array(), "Array: tags is array");
    assert_eq(doc.records[0].at("tags").as_array().size(), 3u, "Array: 3 elements");
}

void test_header() {
    std::string input = std::string() + SOH + "hsv" + US + "1.0" + RS + "type" + US + "users" +
                        STX + "name" + US + "Alice" + ETX;
    auto doc = parse(input);

    assert_true(doc.header.has_value(), "Header: has header");
    assert_eq(get_string(*doc.header, "hsv"), "1.0", "Header: hsv=1.0");
    assert_eq(get_string(*doc.header, "type"), "users", "Header: type=users");
    assert_eq(doc.records.size(), 1u, "Header: 1 record");
}

void test_nesting() {
    std::string input = std::string() + STX + "user" + US + SO +
                        "name" + US + "Alice" + RS + "email" + US + "a@b.com" + SI + ETX;
    auto doc = parse(input);

    assert_eq(doc.records.size(), 1u, "Nesting: 1 record");
    assert_true(doc.records[0].at("user").is_object(), "Nesting: user is object");
    auto& user = doc.records[0].at("user").as_object();
    assert_eq(get_string(user, "name"), "Alice", "Nesting: name=Alice");
    assert_eq(get_string(user, "email"), "a@b.com", "Nesting: email=a@b.com");
}

void test_deep_nesting() {
    std::string input = std::string() + STX + "data" + US + SO +
                        "level1" + US + SO + "level2" + US + "deep" + SI + SI + ETX;
    auto doc = parse(input);

    assert_eq(doc.records.size(), 1u, "Deep nesting: 1 record");
    auto& data = doc.records[0].at("data").as_object();
    auto& level1 = data.at("level1").as_object();
    assert_eq(get_string(level1, "level2"), "deep", "Deep nesting: level2=deep");
}

void test_binary_mode() {
    std::string binary_data = std::string("raw") + STX + "data" + ETX + "here";
    std::string input = std::string() + STX + "type" + US + "image" + RS +
                        "data" + US + DLE + STX + binary_data + DLE + ETX + ETX;
    auto doc = parse(input);

    assert_eq(doc.records.size(), 1u, "Binary: 1 record");
    assert_eq(get_string(doc.records[0], "type"), "image", "Binary: type=image");
    assert_eq(get_string(doc.records[0], "data"), binary_data, "Binary: data preserved");
}

void test_newlines() {
    std::string input = std::string() + STX + "text" + US + "line1\nline2\nline3" + ETX;
    auto doc = parse(input);

    assert_eq(doc.records.size(), 1u, "Newlines: 1 record");
    assert_eq(get_string(doc.records[0], "text"), "line1\nline2\nline3", "Newlines: preserved");
}

void test_quotes() {
    std::string input = std::string() + STX + "msg" + US + "He said \"hello\"" + ETX;
    auto doc = parse(input);

    assert_eq(doc.records.size(), 1u, "Quotes: 1 record");
    assert_eq(get_string(doc.records[0], "msg"), "He said \"hello\"", "Quotes: no escaping");
}

void test_mixed_content() {
    std::string input = std::string("ignored") + STX + "name" + US + "Alice" + ETX + "also ignored";
    auto doc = parse(input);

    assert_eq(doc.records.size(), 1u, "Mixed: 1 record");
    assert_eq(get_string(doc.records[0], "name"), "Alice", "Mixed: name=Alice");
}

void test_multiple_blocks() {
    std::string input = std::string() + STX + "a" + US + "1" + ETX +
                        "junk" + STX + "b" + US + "2" + ETX;
    auto doc = parse(input);

    assert_eq(doc.records.size(), 2u, "Multiple blocks: 2 records");
}

void test_nested_array() {
    std::string input = std::string() + STX + "user" + US + SO +
                        "name" + US + "Alice" + RS + "tags" + US + "admin" + GS + "user" + SI + ETX;
    auto doc = parse(input);

    assert_eq(doc.records.size(), 1u, "Nested array: 1 record");
    auto& user = doc.records[0].at("user").as_object();
    assert_eq(get_string(user, "name"), "Alice", "Nested array: name=Alice");
    assert_true(user.at("tags").is_array(), "Nested array: tags is array");
    assert_eq(user.at("tags").as_array().size(), 2u, "Nested array: 2 tags");
}

int main() {
    std::cout << "==================================================\n";
    std::cout << "HSV Parser Tests (C++)\n";
    std::cout << "==================================================\n";

    test_basic();
    test_multiple_records();
    test_array_values();
    test_header();
    test_nesting();
    test_deep_nesting();
    test_binary_mode();
    test_newlines();
    test_quotes();
    test_mixed_content();
    test_multiple_blocks();
    test_nested_array();

    std::cout << "==================================================\n";
    std::cout << passed << " passed, " << failed << " failed\n";
    std::cout << "==================================================\n";

    return failed > 0 ? 1 : 0;
}