• String.cpp
  • #define CATCH_CONFIG_MAIN
    #define WINDOWS_LEAN_AND_MEAN
    
    #include <catch.h>
    #include <Gorgon/String.h>
    #include <Gorgon/String/Tokenizer.h>
    #include <Gorgon/Types.h>
    #include <map>
    #include <vector>
    #include <set>
    #include <string>
    
    using namespace Gorgon;
    
    
    TEST_CASE("Gorgon::String - To<T> Conversion (Safe)") {
        REQUIRE(String::To<int>("42") == 42);
        REQUIRE(String::To<float>("3.14") == Approx(3.14f));
        REQUIRE(String::To<double>("2.718") == Approx(2.718));
    
        REQUIRE(String::To<int>(std::string("42")) == 42);
        REQUIRE(String::To<float>(std::string("3.14")) == Approx(3.14f));
    
        REQUIRE(String::To<int>("") == 0);
        REQUIRE(String::To<float>("abc") == Approx(0.0f));
        REQUIRE(String::To<int>("1.2.3") == 1);
    }
    
    TEST_CASE("Gorgon::String - From<T> Conversion") {
        REQUIRE(String::From(42) == "42");
        REQUIRE(String::From(3.14f).substr(0, 4) == "3.14");
        REQUIRE(String::From(true) == "1");
        REQUIRE(String::From(false) == "0");
    }
    
    TEST_CASE("Gorgon::String - Replace Function") {
        REQUIRE(String::Replace("hello world, world!", "world", "Earth") == "hello Earth, Earth!");
        REQUIRE(String::Replace("Hello World", "world", "Earth") == "Hello World");
        REQUIRE(String::Replace("aaaaa", "a", "ab") == "ababababab");
    }
    
    TEST_CASE("Gorgon::String - Case Conversion (ASCII only)") {
        REQUIRE(String::ToUpper("test") == "TEST");
        REQUIRE(String::ToLower("TEST") == "test");
    }
    
    TEST_CASE("Gorgon::String - Trim Functions") {
        REQUIRE(String::Trim("   test   ") == "test");
        REQUIRE(String::TrimStart("   test") == "test");
        REQUIRE(String::TrimEnd("test   ") == "test");
    }
    
    TEST_CASE("Gorgon::String - Pad Functions") {
        REQUIRE(String::PadStart("test", 6, '_') == "__test");
        REQUIRE(String::PadEnd("test", 6, '_') == "test__");
    }
    
    TEST_CASE("Gorgon::String - Join Functions") {
        std::vector<int> vec = {1, 2, 3};
        REQUIRE(String::Join(vec, "-") == "1-2-3");
    
        std::map<std::string, int> m = {{"a", 1}, {"b", 2}};
        std::string joined = String::Join(m, ": ", ", ");
        std::set<std::string> valid_outputs = {
            "a: 1, b: 2",
            "b: 2, a: 1"
        };
        REQUIRE(valid_outputs.count(joined) == 1);
    }
    
    TEST_CASE("Gorgon::String - Split Function") {
        std::string input = "a,b,c";
        auto result = String::Split<>(input, ',');
        REQUIRE(result.size() == 3);
        REQUIRE(result[0] == "a");
        REQUIRE(result[1] == "b");
        REQUIRE(result[2] == "c");
    }
    
    TEST_CASE("Gorgon::String - Extract Function") {
        std::string data = "this is a test text";
        REQUIRE(String::Extract(data, ' ') == "this");
        REQUIRE(data == "is a test text");
    
        data = "one,two,three";
        REQUIRE(String::Extract(data, ',') == "one");
        REQUIRE(String::Extract(data, ',') == "two");
        REQUIRE(String::Extract(data, ',') == "three");
    }
    
    TEST_CASE("Gorgon::String - Extract with Quotes") {
        std::string input = "'a,b',c,d";
        REQUIRE(String::Extract_UseQuotes(input, ',') == "'a,b'");
        REQUIRE(String::Extract_UseQuotes(input, ',') == "c");
        REQUIRE(String::Extract_UseQuotes(input, ',') == "d");
    }
    
    TEST_CASE("Gorgon::String - Tokenizer Functionality") {
        std::string data = "this is a test";
        String::Tokenizer tokenizer(data, " ");
        std::vector<std::string> expected = {"this", "is", "a", "test"};
    
        size_t i = 0;
        for (; tokenizer.IsValid(); tokenizer.Next()) {
            REQUIRE(*tokenizer == expected[i]);
            ++i;
        }
    }
    
    TEST_CASE("Gorgon::String - FixLineEndings") {
        REQUIRE(String::FixLineEndings("--\x0d--\x0a--\x0d\x0a--") == "--\x0d\x0a--\x0d\x0a--\x0d\x0a--");
        REQUIRE(String::FixLineEndings("--\x0d--\x0a--\x0d\x0a--", String::LineEnding::LF) == "--\x0a--\x0a--\x0a--");
        REQUIRE(String::FixLineEndings("--\x0d--\x0a--\x0d\x0a--", String::LineEnding::CR) == "--\x0d--\x0d--\x0d--");
        REQUIRE(String::FixLineEndings("--\x0d--\x0a--\x0d\x0a--", String::LineEnding::None) == "--------");
    }